GammaLib 2.1.0.dev
Loading...
Searching...
No Matches
GNdarray.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GNdarray.cpp - N-dimensional array class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2016-2022 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GNdarray.cpp
23 * @brief N-dimensional array class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GTools.hpp"
32#include "GException.hpp"
33#include "GNdarray.hpp"
34
35
36/* __ Method name definitions ____________________________________________ */
37#define G_OP_ADD "GNdarray::operator+=(GNdarray&)"
38#define G_OP_SUB "GNdarray::operator-=(GNdarray&)"
39#define G_OP_MUL "GNdarray::operator*=(GNdarray&)"
40#define G_OP_DIV "GNdarray::operator/=(GNdarray&)"
41#define G_SHAPE "GNdarray::shape(std::vector<int>&)"
42#define G_AT1 "GNdarray::at(int&)"
43#define G_AT2 "GNdarray::at(int&, int&)"
44#define G_AT3 "GNdarray::at(int&, int&, int&)"
45#define G_ATN "GNdarray::at(std::vector<int>&)"
46
47
48/*==========================================================================
49 = =
50 = Constructors/destructors =
51 = =
52 ==========================================================================*/
53
54/***********************************************************************//**
55 * @brief Void constructor
56 ***************************************************************************/
58{
59 // Initialise class members
61
62 // Return
63 return;
64}
65
66
67/***********************************************************************//**
68 * @brief 1-dimensional constructor
69 *
70 * @param[in] nx Array dimension.
71 *
72 * Constructs a 1-dimensional array.
73 ***************************************************************************/
74GNdarray::GNdarray(const int& nx)
75{
76 // Initialise class members
78
79 // Set shape
80 m_shape.push_back(nx);
81
82 // Set strides
83 m_strides.push_back(1);
84
85 // Initialise data array with zeros
86 m_data.assign(nx, 0.0);
87
88 // Return
89 return;
90}
91
92
93/***********************************************************************//**
94 * @brief 2-dimensional constructor
95 *
96 * @param[in] nx Array's first dimension.
97 * @param[in] ny Array's second dimension.
98 *
99 * Constructs a 2-dimensional array.
100 ***************************************************************************/
101GNdarray::GNdarray(const int& nx, const int& ny)
102{
103 // Initialise class members
104 init_members();
105
106 // Compute size of array
107 int size = nx * ny;
108
109 // Set shape
110 m_shape.push_back(nx);
111 m_shape.push_back(ny);
112
113 // Set strides
114 m_strides.push_back(1);
115 m_strides.push_back(nx);
116
117 // Initialise data array with zeros
118 m_data.assign(size, 0.0);
119
120 // Return
121 return;
122}
123
124
125/***********************************************************************//**
126 * @brief 3-dimensional constructor
127 *
128 * @param[in] nx Array's first dimension.
129 * @param[in] ny Array's second dimension.
130 * @param[in] nz Array's third dimension.
131 *
132 * Constructs a 3-dimensional array.
133 ***************************************************************************/
134GNdarray::GNdarray(const int& nx, const int& ny, const int& nz)
135{
136 // Initialise class members
137 init_members();
138
139 // Compute size of array
140 int size = nx * ny * nz;
141
142 // Set shape
143 m_shape.push_back(nx);
144 m_shape.push_back(ny);
145 m_shape.push_back(nz);
146
147 // Set strides
148 m_strides.push_back(1);
149 m_strides.push_back(nx);
150 m_strides.push_back(nx*ny);
151
152 // Initialise data array with zeros
153 m_data.assign(size, 0.0);
154
155 // Return
156 return;
157}
158
159
160/***********************************************************************//**
161 * @brief n-dimensional constructor
162 *
163 * @param[in] n Array dimensions.
164 *
165 * Constructs a n-dimensional array. If the array dimension vector @p n is
166 * empty an empty n-dimensional array is constructed (similar to the void
167 * constructor).
168 ***************************************************************************/
169GNdarray::GNdarray(const std::vector<int>& n)
170{
171 // Initialise class members
172 init_members();
173
174 // Continue only if there are dimensions in vector
175 if (n.size() > 0) {
176
177 // Compute size of array
178 int size = n[0];
179 for (int i = 1; i < n.size(); ++i) {
180 size *= n[i];
181 }
182
183 // Set shape
184 m_shape = n;
185
186 // Set strides
187 int stride = 1;
188 for (int i = 0; i < n.size(); ++i) {
189 m_strides.push_back(stride);
190 stride *= n[i];
191 }
192
193 // Initialise data array with zeros
194 m_data.assign(size, 0.0);
195
196 } // endif: there were dimensions in vector
197
198 // Return
199 return;
200}
201
202
203/***********************************************************************//**
204 * @brief Copy constructor
205 *
206 * @param[in] array Array.
207 ***************************************************************************/
209{
210 // Initialise class members
211 init_members();
212
213 // Copy members
214 copy_members(array);
215
216 // Return
217 return;
218}
219
220
221/***********************************************************************//**
222 * @brief Destructor
223 ***************************************************************************/
225{
226 // Free members
227 free_members();
228
229 // Return
230 return;
231}
232
233
234/*==========================================================================
235 = =
236 = Operators =
237 = =
238 ==========================================================================*/
239
240/***********************************************************************//**
241 * @brief Assignment operator
242 *
243 * @param[in] array Array.
244 * @return Array.
245 ***************************************************************************/
247{
248 // Execute only if object is not identical
249 if (this != &array) {
250
251 // Free members
252 free_members();
253
254 // Initialise private members
255 init_members();
256
257 // Copy members
258 copy_members(array);
259
260 } // endif: object was not identical
261
262 // Return this object
263 return *this;
264}
265
266
267/***********************************************************************//**
268 * @brief Equality operator
269 *
270 * @param[in] array Array.
271 * @return True if arrays are identical.
272 *
273 * Returns true if the arrays have identical shape and content.
274 ***************************************************************************/
275bool GNdarray::operator==(const GNdarray& array) const
276{
277 // Check of arrays have the same shape
278 bool identity = has_same_shape(array);
279
280 // If the arrays have identical dimensions then check if all elements
281 // are identical. Break as soon as one array element differs.
282 if (identity) {
283 for (int i = 0; i < m_data.size(); ++i) {
284 if (m_data[i] != array.m_data[i]) {
285 identity = false;
286 break;
287 }
288 }
289 }
290
291 // Return result
292 return identity;
293}
294
295
296/***********************************************************************//**
297 * @brief Non-equality operator
298 *
299 * @param[in] array Array.
300 * @return True if arrays are different.
301 *
302 * Returns true if the arrays have different shape or content.
303 ***************************************************************************/
304bool GNdarray::operator!=(const GNdarray& array) const
305{
306 // Get negated result of equality operation
307 bool difference = !(this->operator==(array));
308
309 // Return result
310 return difference;
311}
312
313
314/***********************************************************************//**
315 * @brief Unary addition operator
316 *
317 * @param[in] array Array.
318 * @return Array.
319 *
320 * Adds an array to the current array.
321 ***************************************************************************/
323{
324 // Throw an exception if the arrays have not the same shape
326
327 // Add elements
328 for (int i = 0; i < m_data.size(); ++i) {
329 m_data[i] += array.m_data[i];
330 }
331
332 // Return array
333 return *this;
334}
335
336
337/***********************************************************************//**
338 * @brief Unary multiplication operator
339 *
340 * @param[in] array Array.
341 * @return Array.
342 *
343 * Multiply an array by the current array.
344 ***************************************************************************/
346{
347 // Throw an exception if the arrays have not the same shape
349
350 // Multiply elements
351 for (int i = 0; i < m_data.size(); ++i) {
352 m_data[i] *= array.m_data[i];
353 }
354
355 // Return array
356 return *this;
357}
358
359
360/***********************************************************************//**
361 * @brief Unary division operator
362 *
363 * @param[in] array Array.
364 * @return Array.
365 *
366 * Divide current array by array.
367 ***************************************************************************/
369{
370 // Throw an exception if the arrays have not the same shape
372
373 // Divide elements
374 for (int i = 0; i < m_data.size(); ++i) {
375
376 // Only proceed if second array is non zero
377 if (array.m_data[i] != 0.0){
378 m_data[i] /= array.m_data[i];
379 }
380
381 // ... otherwise set ratio to 0
382 else {
383 m_data[i] = 0.0;
384 }
385
386 } // endfor: looped over array elements
387
388 // Return array
389 return *this;
390}
391
392
393/***********************************************************************//**
394 * @brief Unary subtraction operator
395 *
396 * @param[in] array Array.
397 * @return Array.
398 *
399 * Subtracts an array from the current array.
400 ***************************************************************************/
402{
403 // Throw an exception if the arrays have not the same shape
405
406 // Subtract elements
407 for (int i = 0; i < m_data.size(); ++i) {
408 m_data[i] -= array.m_data[i];
409 }
410
411 // Return array
412 return *this;
413}
414
415
416/***********************************************************************//**
417 * @brief Unary value addition operator
418 *
419 * @param[in] value Value.
420 * @return Array.
421 *
422 * Adds a value to all array elements.
423 ***************************************************************************/
424GNdarray& GNdarray::operator+=(const double& value)
425{
426 // Add value to elements
427 for (int i = 0; i < m_data.size(); ++i) {
428 m_data[i] += value;
429 }
430
431 // Return array
432 return *this;
433}
434
435
436/***********************************************************************//**
437 * @brief Unary value subtraction operator
438 *
439 * @param[in] value Value.
440 * @return Array.
441 *
442 * Subtracts a value from all array elements.
443 ***************************************************************************/
444GNdarray& GNdarray::operator-=(const double& value)
445{
446 // Subtract value from elements
447 for (int i = 0; i < m_data.size(); ++i) {
448 m_data[i] -= value;
449 }
450
451 // Return array
452 return *this;
453}
454
455
456/***********************************************************************//**
457 * @brief Unary multiplication operator
458 *
459 * @param[in] value Value.
460 * @return Array.
461 *
462 * Multiply all array elements by a value.
463 ***************************************************************************/
464GNdarray& GNdarray::operator*=(const double& value)
465{
466 // Multiply all elements
467 for (int i = 0; i < m_data.size(); ++i) {
468 m_data[i] *= value;
469 }
470
471 // Return array
472 return *this;
473}
474
475
476/***********************************************************************//**
477 * @brief Unary division operator
478 *
479 * @param[in] value Value.
480 * @return Array.
481 *
482 * Divide all array elements by a value.
483 ***************************************************************************/
484GNdarray& GNdarray::operator/=(const double& value)
485{
486 // Divide all elements
487 for (int i = 0; i < m_data.size(); ++i) {
488 m_data[i] /= value;
489 }
490
491 // Return array
492 return *this;
493}
494
495
496/***********************************************************************//**
497 * @brief Unary minus operator
498 *
499 * @return Array.
500 *
501 * Negate all array elements.
502 ***************************************************************************/
504{
505 // Copy array
506 GNdarray result = *this;
507
508 // Negate all elements
509 for (int i = 0; i < m_data.size(); ++i) {
510 result.m_data[i] = -result.m_data[i];
511 }
512
513 // Return array
514 return result;
515}
516
517
518/*==========================================================================
519 = =
520 = Public methods =
521 = =
522 ==========================================================================*/
523
524/***********************************************************************//**
525 * @brief Clear array
526 ***************************************************************************/
528{
529 // Free members
530 free_members();
531
532 // Initialise private members
533 init_members();
534
535 // Return
536 return;
537}
538
539
540/***********************************************************************//**
541 * @brief Clone array
542 *
543 * @return Pointer to deep copy of array.
544 ***************************************************************************/
546{
547 // Clone array
548 return new GNdarray(*this);
549}
550
551
552/***********************************************************************//**
553 * @brief Set shape of array
554 *
555 * @param[in] shape Shape vector.
556 *
557 * @exception GException::invalid_argument
558 * Invalid shape factorisation specified.
559 *
560 * Set the shape of the array. The shape specifies how the information is
561 * arranged in a n-dimensional array.
562 ***************************************************************************/
563void GNdarray::shape(const std::vector<int>& shape)
564{
565 // Computes the number of array elements
566 int nelements = 0;
567 if (shape.size() > 0) {
568 nelements = 1;
569 for (int i = 0; i < shape.size(); ++i) {
570 nelements *= shape[i];
571 }
572 }
573
574 // Throw an exception if resulting number of elements is not equal to
575 // the existing number of elements
576 if (nelements != size()) {
577 std::string msg = "Number of elements "+gammalib::str(nelements)+
578 " in specified shape is not identical to the "
579 "number of elements "+gammalib::str(size())+
580 " in the array.";
582 }
583
584 // Set shape
585 m_shape = shape;
586
587 // Return
588 return;
589}
590
591
592/***********************************************************************//**
593 * @brief 1-dimensional array element access with range checking
594 * (const version)
595 *
596 * @param[in] ix Element index [0,...,shape(0)-1].
597 * @return Const reference to array element.
598 *
599 * @exception GException::invalid_value
600 * Array is not 1-dimensional.
601 * @exception GException::out_of_range
602 * Element index is out of range.
603 ***************************************************************************/
604const double& GNdarray::at(const int& ix) const
605{
606 // Throw an exception if the array is not 1-dimensional
607 if (m_shape.size() != 1) {
608 std::string msg = "Invalid access of "+
609 gammalib::str(m_shape.size())+"-dimensional array "
610 "with 1-dimensional access operator.";
612 }
613
614 // Throw an exception if the index is outside the valid range
615 if (ix < 0 || ix >= m_shape[0]) {
616 throw GException::out_of_range(G_AT1, "Array index", ix, m_shape[0]);
617 }
618
619 // Return array element
620 return (*this)(ix);
621}
622
623
624/***********************************************************************//**
625 * @brief 2-dimensional array element access with range checking
626 * (const version)
627 *
628 * @param[in] ix Index in first dimension [0,...,shape(0)-1].
629 * @param[in] iy Index in second dimension [0,...,shape(1)-1].
630 * @return Const reference to array element.
631 *
632 * @exception GException::invalid_value
633 * Array is not 2-dimensional.
634 * @exception GException::out_of_range
635 * Element index is out of range.
636 ***************************************************************************/
637const double& GNdarray::at(const int& ix, const int& iy) const
638{
639 // Throw an exception if the array is not 2-dimensional
640 if (m_shape.size() != 2) {
641 std::string msg = "Invalid access of "+
642 gammalib::str(m_shape.size())+"-dimensional array "
643 "with 2-dimensional access operator.";
645 }
646
647 // Throw an exception if the indices are outside the valid range
648 if (ix < 0 || ix >= m_shape[0]) {
649 throw GException::out_of_range(G_AT2, "First array index", ix,
650 m_shape[0]);
651 }
652 if (iy < 0 || iy >= m_shape[1]) {
653 throw GException::out_of_range(G_AT2, "Second array index", iy,
654 m_shape[1]);
655 }
656
657 // Return array element
658 return (*this)(ix,iy);
659}
660
661
662/***********************************************************************//**
663 * @brief 3-dimensional array element access with range checking
664 * (const version)
665 *
666 * @param[in] ix Index in first dimension [0,...,shape(0)-1].
667 * @param[in] iy Index in second dimension [0,...,shape(1)-1].
668 * @param[in] iz Index in third dimension [0,...,shape(2)-1].
669 * @return Const reference to array element.
670 *
671 * @exception GException::invalid_value
672 * Array is not 3-dimensional.
673 * @exception GException::out_of_range
674 * Element index is out of range.
675 ***************************************************************************/
676const double& GNdarray::at(const int& ix, const int& iy, const int& iz) const
677{
678 // Throw an exception if the array is not 2-dimensional
679 if (m_shape.size() != 3) {
680 std::string msg = "Invalid access of "+
681 gammalib::str(m_shape.size())+"-dimensional array "
682 "with 3-dimensional access operator.";
684 }
685
686 // Throw an exception if the indices are outside the valid range
687 if (ix < 0 || ix >= m_shape[0]) {
688 throw GException::out_of_range(G_AT3, "First array index", ix,
689 m_shape[0]);
690 }
691 if (iy < 0 || iy >= m_shape[1]) {
692 throw GException::out_of_range(G_AT3, "Second array index", iy,
693 m_shape[1]);
694 }
695 if (iz < 0 || iz >= m_shape[2]) {
696 throw GException::out_of_range(G_AT3, "Third array index", iz,
697 m_shape[2]);
698 }
699
700 // Return array element
701 return (*this)(ix,iy,iz);
702}
703
704
705/***********************************************************************//**
706 * @brief n-dimensional array element access with range checking
707 * (const version)
708 *
709 * @param[in] i Index vector.
710 * @return Const reference to array element.
711 *
712 * @exception GException::invalid_value
713 * Array is not of correct dimension.
714 * @exception GException::out_of_range
715 * Element index is out of range.
716 ***************************************************************************/
717const double& GNdarray::at(const std::vector<int>& i) const
718{
719 // Throw an exception if the array is not 2-dimensional
720 if (m_shape.size() != i.size()) {
721 std::string msg = "Invalid access of "+
722 gammalib::str(m_shape.size())+"-dimensional array "
723 "with "+
724 gammalib::str(i.size())+"-dimensional access "
725 "operator.";
727 }
728
729 // Throw an exception if the indices are outside the valid range
730 for (int k = 0; k < m_shape.size(); ++k) {
731 if (i[k] < 0 || i[k] >= m_shape[k]) {
732 throw GException::out_of_range(G_ATN, "Dimension "+
733 gammalib::str(k)+" index",
734 i[k], m_shape[k]);
735 }
736 }
737
738 // Return array element
739 return (*this)(i);
740}
741
742
743/***********************************************************************//**
744 * @brief Compute array element index
745 *
746 * @param[in] i Index vector.
747 * @return Array element index.
748 *
749 * Computes the array element index from an index vector. The method assumes
750 * that the index vector has the same dimension as the array. If this
751 * condition is not guaranteed, the condition needs to be checked before
752 * calling the method.
753 ***************************************************************************/
754int GNdarray::index(const std::vector<int>& i) const
755{
756 // Initialise element index
757 int index = 0;
758
759 // Compute element index
760 for (int k = 0; k < m_shape.size(); ++k) {
761 index += m_strides[k] * i[k];
762 }
763
764 // Return index
765 return index;
766}
767
768
769/***********************************************************************//**
770* @brief Compute index vector
771*
772* @param[in] index Array element index.
773* @return Index vector.
774*
775* Computes index vector from an array element index.
776***************************************************************************/
777std::vector<int> GNdarray::index(const int& index) const
778{
779 // Get number of array dimensions
780 int dim = m_shape.size();
781
782 // Set working index
783 int inx = index;
784
785 // Initialise index vector
786 std::vector<int> i(dim, 0);
787
788 // Compute index vector
789 for (int k = dim-1; k >= 0; --k) {
790 int strides = m_strides[k];
791 i[k] = inx / strides;
792 inx -= strides * i[k];
793 }
794
795 // Return index vector
796 return i;
797}
798
799
800/***********************************************************************//**
801 * @brief Print array information
802 *
803 * @param[in] chatter Chattiness.
804 * @return String containing array information.
805 ***************************************************************************/
806std::string GNdarray::print(const GChatter& chatter) const
807{
808 // Initialise result string
809 std::string result = "(";
810
811 // Continue only if chatter is not silent
812 if (chatter != SILENT) {
813
814 // Put all elements in string
815 for (int i = 0; i < m_data.size(); ++i) {
816 if (i > 0) {
817 result += ", ";
818 }
819 result += gammalib::str(m_data[i]);
820 }
821
822 // Append closing parentheses
823 result += ")";
824
825 } // endif: chatter was not silent
826
827 // Return result
828 return result;
829}
830
831
832/*==========================================================================
833 = =
834 = Private methods =
835 = =
836 ==========================================================================*/
837
838/***********************************************************************//**
839 * @brief Initialise class members
840 ***************************************************************************/
842{
843 // Initialise members
844 m_shape.clear();
845 m_strides.clear();
846 m_data.clear();
847
848 // Actually reallocate the memory of m_data
849 std::vector<double>(m_data).swap(m_data);
850
851 // Return
852 return;
853}
854
855
856/***********************************************************************//**
857 * @brief Copy class members
858 *
859 * @param[in] array Array.
860 ***************************************************************************/
862{
863 // Copy members
864 m_shape = array.m_shape;
865 m_strides = array.m_strides;
866 m_data = array.m_data;
867
868 // Return
869 return;
870}
871
872
873/***********************************************************************//**
874 * @brief Delete class members
875 ***************************************************************************/
877{
878 // Return
879 return;
880}
881
882
883/***********************************************************************//**
884 * @brief Check if array has the same shape
885 *
886 * @param[in] array Array.
887 * @return True if the array has the same shape.
888 ***************************************************************************/
889bool GNdarray::has_same_shape(const GNdarray& array) const
890{
891 // Check if the array has the same dimension
892 bool identity = m_shape.size() == array.m_shape.size();
893
894 // Check if the shape is identical. Break as soon as one shape value
895 // differs.
896 if (identity) {
897 for (int i = 0; i < m_shape.size(); ++i) {
898 if (m_shape[i] != array.m_shape[i]) {
899 identity = false;
900 break;
901 }
902 }
903 }
904
905 // Return result
906 return identity;
907}
908
909
910/***********************************************************************//**
911 * @brief Throw exception if array shapes differ
912 *
913 * @param[in] method Method that throws exception.
914 * @param[in] array Array.
915 ***************************************************************************/
916void GNdarray::require_same_shape(const std::string& method,
917 const GNdarray& array) const
918{
919 // If the shape differs then throw an exception
920 if (!has_same_shape(array)) {
921
922 // Compose exception message
923 std::string msg = "Incompatible array dimensions (";
924 for (int i = 0; i < m_shape.size(); ++i) {
925 if (i > 0) {
926 msg += ", ";
927 }
928 msg += gammalib::str(m_shape[i]);
929 }
930 msg += ") <=> (";
931 for (int i = 0; i < array.m_shape.size(); ++i) {
932 if (i > 0) {
933 msg += ", ";
934 }
935 msg += gammalib::str(array.m_shape[i]);
936 }
937 msg += ").";
938
939 // Throw exception
940 throw GException::invalid_argument(method, msg);
941
942 } // endif: array shapes differed
943
944 // Return
945 return;
946}
947
948
949/*==========================================================================
950 = =
951 = Friends =
952 = =
953 ==========================================================================*/
954
955/***********************************************************************//**
956 * @brief Computes minimum array element
957 *
958 * @param[in] array Array.
959 * @return Minimum array element.
960 ***************************************************************************/
961double min(const GNdarray& array)
962{
963 // Initialises result
964 double result = 0.0;
965
966 // Continue only if we have elements
967 if (array.m_data.size() > 0) {
968
969 // Search for minimum
970 result = array.m_data[0];
971 for (int i = 1; i < array.m_data.size(); ++i) {
972 if (array.m_data[i] < result) {
973 result = array.m_data[i];
974 }
975 }
976
977 } // endif: there were elements
978
979 // Returns minimum
980 return result;
981}
982
983
984/***********************************************************************//**
985 * @brief Computes maximum array element
986 *
987 * @param[in] array Array.
988 * @return Maximum array element.
989 ***************************************************************************/
990double max(const GNdarray& array)
991{
992 // Initialises result
993 double result = 0.0;
994
995 // Continue only if we have elements
996 if (array.m_data.size() > 0) {
997
998 // Search for maximum
999 result = array.m_data[0];
1000 for (int i = 1; i < array.m_data.size(); ++i) {
1001 if (array.m_data[i] > result) {
1002 result = array.m_data[i];
1003 }
1004 }
1005
1006 } // endif: there were elements
1007
1008 // Returns maximum
1009 return result;
1010}
1011
1012
1013/***********************************************************************//**
1014 * @brief Computes array sum
1015 *
1016 * @param[in] array Array.
1017 * @return Sum of array elements.
1018 ***************************************************************************/
1019double sum(const GNdarray& array)
1020{
1021 // Compute sum
1022 double result = 0.0;
1023 for (int i = 0; i < array.m_data.size(); ++i) {
1024 result += array.m_data[i];
1025 }
1026
1027 // Returns sum
1028 return result;
1029}
1030
1031
1032/***********************************************************************//**
1033 * @brief Computes arccos of array elements
1034 *
1035 * @param[in] array Array.
1036 * @return Array containing the arccos of every element.
1037 ***************************************************************************/
1039{
1040 // Initialise result array
1041 GNdarray result = array;
1042
1043 // Evaluate each array element
1044 for (int i = 0; i < array.m_data.size(); ++i) {
1045 result.m_data[i] = std::acos(array.m_data[i]);
1046 }
1047
1048 // Return array
1049 return result;
1050}
1051
1052
1053/***********************************************************************//**
1054 * @brief Computes acosh of array elements
1055 *
1056 * @param[in] array Array.
1057 * @return Array containing the acosh of every element.
1058 ***************************************************************************/
1060{
1061 // Initialise result array
1062 GNdarray result = array;
1063
1064 // Evaluate each array element
1065 for (int i = 0; i < array.m_data.size(); ++i) {
1066 result.m_data[i] = acosh(array.m_data[i]);
1067 }
1068
1069 // Return array
1070 return result;
1071}
1072
1073
1074/***********************************************************************//**
1075 * @brief Computes arcsin of array elements
1076 *
1077 * @param[in] array Array.
1078 * @return Array containing the arcsin of every element.
1079 ***************************************************************************/
1081{
1082 // Initialise result array
1083 GNdarray result = array;
1084
1085 // Evaluate each array element
1086 for (int i = 0; i < array.m_data.size(); ++i) {
1087 result.m_data[i] = std::asin(array.m_data[i]);
1088 }
1089
1090 // Return array
1091 return result;
1092}
1093
1094
1095/***********************************************************************//**
1096 * @brief Computes asinh of array elements
1097 *
1098 * @param[in] array Array.
1099 * @return Array containing the asinh of every element.
1100 ***************************************************************************/
1102{
1103 // Initialise result array
1104 GNdarray result = array;
1105
1106 // Evaluate each array element
1107 for (int i = 0; i < array.m_data.size(); ++i) {
1108 result.m_data[i] = asinh(array.m_data[i]);
1109 }
1110
1111 // Return array
1112 return result;
1113}
1114
1115
1116/***********************************************************************//**
1117 * @brief Computes arctan of array elements
1118 *
1119 * @param[in] array Array.
1120 * @return Array containing the arctan of every element.
1121 ***************************************************************************/
1123{
1124 // Initialise result array
1125 GNdarray result = array;
1126
1127 // Evaluate each array element
1128 for (int i = 0; i < array.m_data.size(); ++i) {
1129 result.m_data[i] = std::atan(array.m_data[i]);
1130 }
1131
1132 // Return array
1133 return result;
1134}
1135
1136
1137/***********************************************************************//**
1138 * @brief Computes atanh of array elements
1139 *
1140 * @param[in] array Array.
1141 * @return Array containing the atanh of every element.
1142 ***************************************************************************/
1144{
1145 // Initialise result array
1146 GNdarray result = array;
1147
1148 // Evaluate each array element
1149 for (int i = 0; i < array.m_data.size(); ++i) {
1150 result.m_data[i] = atanh(array.m_data[i]);
1151 }
1152
1153 // Return array
1154 return result;
1155}
1156
1157
1158/***********************************************************************//**
1159 * @brief Computes cosine of array elements
1160 *
1161 * @param[in] array Array.
1162 * @return Array containing the cosine of every element.
1163 ***************************************************************************/
1164GNdarray cos(const GNdarray& array)
1165{
1166 // Initialise result array
1167 GNdarray result = array;
1168
1169 // Evaluate each array element
1170 for (int i = 0; i < array.m_data.size(); ++i) {
1171 result.m_data[i] = std::cos(array.m_data[i]);
1172 }
1173
1174 // Return array
1175 return result;
1176}
1177
1178
1179/***********************************************************************//**
1180 * @brief Computes cosh of array elements
1181 *
1182 * @param[in] array Array.
1183 * @return Array containing the cosh of every element.
1184 ***************************************************************************/
1186{
1187 // Initialise result array
1188 GNdarray result = array;
1189
1190 // Evaluate each array element
1191 for (int i = 0; i < array.m_data.size(); ++i) {
1192 result.m_data[i] = std::cosh(array.m_data[i]);
1193 }
1194
1195 // Return array
1196 return result;
1197}
1198
1199
1200/***********************************************************************//**
1201 * @brief Computes exponential of array elements
1202 *
1203 * @param[in] array Array.
1204 * @return Array containing the exponential of every element.
1205 ***************************************************************************/
1206GNdarray exp(const GNdarray& array)
1207{
1208 // Initialise result array
1209 GNdarray result = array;
1210
1211 // Evaluate each array element
1212 for (int i = 0; i < array.m_data.size(); ++i) {
1213 result.m_data[i] = std::exp(array.m_data[i]);
1214 }
1215
1216 // Return array
1217 return result;
1218}
1219
1220
1221/***********************************************************************//**
1222 * @brief Computes absolute of array elements
1223 *
1224 * @param[in] array Array.
1225 * @return Array containing the absolute of every element.
1226 ***************************************************************************/
1227GNdarray abs(const GNdarray& array)
1228{
1229 // Initialise result array
1230 GNdarray result = array;
1231
1232 // Evaluate each array element
1233 for (int i = 0; i < array.m_data.size(); ++i) {
1234 result.m_data[i] = std::abs(array.m_data[i]);
1235 }
1236
1237 // Return array
1238 return result;
1239}
1240
1241
1242/***********************************************************************//**
1243 * @brief Computes natural logarithm of array elements
1244 *
1245 * @param[in] array Array.
1246 * @return Array containing the natural logarithm of every element.
1247 ***************************************************************************/
1248GNdarray log(const GNdarray& array)
1249{
1250 // Initialise result array
1251 GNdarray result = array;
1252
1253 // Evaluate each array element
1254 for (int i = 0; i < array.m_data.size(); ++i) {
1255 result.m_data[i] = std::log(array.m_data[i]);
1256 }
1257
1258 // Return array
1259 return result;
1260}
1261
1262
1263/***********************************************************************//**
1264 * @brief Computes sign of array elements
1265 *
1266 * @param[in] array Array.
1267 * @return Array containing the sign of every element.
1268 ***************************************************************************/
1270{
1271 // Initialise result array
1272 GNdarray result = array;
1273
1274 // Evaluate each array element
1275 for (int i = 0; i < array.m_data.size(); ++i) {
1276
1277 // Get array content
1278 double content = array.m_data[i];
1279
1280 // Initialise sign
1281 double sign;
1282
1283 // Handle the 3 cases
1284 if (content < 0.0) {
1285 sign = -1.0;
1286 }
1287 else if (content > 0.0) {
1288 sign = +1.0;
1289 }
1290 else {
1291 sign = 0.0;
1292 }
1293
1294 // Store sign
1295 result.m_data[i] = sign;
1296
1297 } // endfor: looped over all array elements
1298
1299 // Return array
1300 return result;
1301}
1302
1303
1304/***********************************************************************//**
1305 * @brief Computes base10 logarithm of array elements
1306 *
1307 * @param[in] array Array.
1308 * @return Array containing the base10 logarithm of every element.
1309 ***************************************************************************/
1311{
1312 // Initialise result array
1313 GNdarray result = array;
1314
1315 // Evaluate each array element
1316 for (int i = 0; i < array.m_data.size(); ++i) {
1317 result.m_data[i] = std::log10(array.m_data[i]);
1318 }
1319
1320 // Return array
1321 return result;
1322}
1323
1324
1325/***********************************************************************//**
1326 * @brief Computes sine of array elements
1327 *
1328 * @param[in] array Array.
1329 * @return Array containing the sine of every element.
1330 ***************************************************************************/
1331GNdarray sin(const GNdarray& array)
1332{
1333 // Initialise result array
1334 GNdarray result = array;
1335
1336 // Evaluate each array element
1337 for (int i = 0; i < array.m_data.size(); ++i) {
1338 result.m_data[i] = std::sin(array.m_data[i]);
1339 }
1340
1341 // Return array
1342 return result;
1343}
1344
1345
1346/***********************************************************************//**
1347 * @brief Computes sinh of array elements
1348 *
1349 * @param[in] array Array.
1350 * @return Array containing the sinh of every element.
1351 ***************************************************************************/
1353{
1354 // Initialise result array
1355 GNdarray result = array;
1356
1357 // Evaluate each array element
1358 for (int i = 0; i < array.m_data.size(); ++i) {
1359 result.m_data[i] = std::sinh(array.m_data[i]);
1360 }
1361
1362 // Return array
1363 return result;
1364}
1365
1366
1367/***********************************************************************//**
1368 * @brief Computes square root of array elements
1369 *
1370 * @param[in] array Array.
1371 * @return Array containing the square root of every element.
1372 ***************************************************************************/
1374{
1375 // Initialise result array
1376 GNdarray result = array;
1377
1378 // Evaluate each array element
1379 for (int i = 0; i < array.m_data.size(); ++i) {
1380 result.m_data[i] = std::sqrt(array.m_data[i]);
1381 }
1382
1383 // Return array
1384 return result;
1385}
1386
1387
1388/***********************************************************************//**
1389 * @brief Computes tangens of array elements
1390 *
1391 * @param[in] array Array.
1392 * @return Array containing the tangens of every element.
1393 ***************************************************************************/
1394GNdarray tan(const GNdarray& array)
1395{
1396 // Initialise result array
1397 GNdarray result = array;
1398
1399 // Evaluate each array element
1400 for (int i = 0; i < array.m_data.size(); ++i) {
1401 result.m_data[i] = std::tan(array.m_data[i]);
1402 }
1403
1404 // Return array
1405 return result;
1406}
1407
1408
1409/***********************************************************************//**
1410 * @brief Computes tanh of array elements
1411 *
1412 * @param[in] array Array.
1413 * @return Array containing the tanh of every element.
1414 ***************************************************************************/
1416{
1417 // Initialise result array
1418 GNdarray result = array;
1419
1420 // Evaluate each array element
1421 for (int i = 0; i < array.m_data.size(); ++i) {
1422 result.m_data[i] = std::tanh(array.m_data[i]);
1423 }
1424
1425 // Return array
1426 return result;
1427}
1428
1429
1430/***********************************************************************//**
1431 * @brief Computes tanh of array elements
1432 *
1433 * @param[in] array Array.
1434 * @param[in] power Power.
1435 * @return Array containing the power of every element.
1436 ***************************************************************************/
1437GNdarray pow(const GNdarray& array, const double& power)
1438{
1439 // Initialise result array
1440 GNdarray result = array;
1441
1442 // Evaluate each array element
1443 for (int i = 0; i < array.m_data.size(); ++i) {
1444 result.m_data[i] = std::pow(array.m_data[i], power);
1445 }
1446
1447 // Return array
1448 return result;
1449}
Exception handler interface definition.
#define G_OP_MUL
Definition GFft.cpp:40
#define G_AT2
Definition GFits.cpp:52
#define G_AT1
Definition GFits.cpp:51
#define G_OP_ADD
Definition GMatrix.cpp:43
#define G_OP_SUB
Definition GMatrix.cpp:44
GNdarray cosh(const GNdarray &array)
Computes cosh of array elements.
double max(const GNdarray &array)
Computes maximum array element.
Definition GNdarray.cpp:990
GNdarray asin(const GNdarray &array)
Computes arcsin of array elements.
GNdarray tanh(const GNdarray &array)
Computes tanh of array elements.
GNdarray sqrt(const GNdarray &array)
Computes square root of array elements.
GNdarray atan(const GNdarray &array)
Computes arctan of array elements.
#define G_AT3
Definition GNdarray.cpp:44
GNdarray asinh(const GNdarray &array)
Computes asinh of array elements.
GNdarray sinh(const GNdarray &array)
Computes sinh of array elements.
#define G_SHAPE
Definition GNdarray.cpp:41
GNdarray acosh(const GNdarray &array)
Computes acosh of array elements.
GNdarray atanh(const GNdarray &array)
Computes atanh of array elements.
double min(const GNdarray &array)
Computes minimum array element.
Definition GNdarray.cpp:961
GNdarray pow(const GNdarray &array, const double &power)
Computes tanh of array elements.
#define G_ATN
Definition GNdarray.cpp:45
double sum(const GNdarray &array)
Computes array sum.
GNdarray acos(const GNdarray &array)
Computes arccos of array elements.
GNdarray log10(const GNdarray &array)
Computes base10 logarithm of array elements.
GNdarray log(const GNdarray &array)
Computes natural logarithm of array elements.
GNdarray sin(const GNdarray &array)
Computes sine of array elements.
GNdarray abs(const GNdarray &array)
Computes absolute of array elements.
GNdarray tan(const GNdarray &array)
Computes tangens of array elements.
GNdarray cos(const GNdarray &array)
Computes cosine of array elements.
GNdarray sign(const GNdarray &array)
Computes sign of array elements.
GNdarray exp(const GNdarray &array)
Computes exponential of array elements.
N-dimensional array class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
#define G_OP_DIV
Definition GVector.cpp:40
N-dimensional array class.
Definition GNdarray.hpp:44
GNdarray & operator*=(const GNdarray &array)
Unary multiplication operator.
Definition GNdarray.cpp:345
void copy_members(const GNdarray &array)
Copy class members.
Definition GNdarray.cpp:861
GNdarray operator-(void) const
Unary minus operator.
Definition GNdarray.cpp:503
void require_same_shape(const std::string &method, const GNdarray &array) const
Throw exception if array shapes differ.
Definition GNdarray.cpp:916
int size(void) const
Return number of elements in array.
Definition GNdarray.hpp:294
bool operator!=(const GNdarray &array) const
Non-equality operator.
Definition GNdarray.cpp:304
std::vector< int > m_shape
Array dimensions.
Definition GNdarray.hpp:136
bool operator==(const GNdarray &array) const
Equality operator.
Definition GNdarray.cpp:275
void clear(void)
Clear array.
Definition GNdarray.cpp:527
std::string print(const GChatter &chatter=NORMAL) const
Print array information.
Definition GNdarray.cpp:806
GNdarray & operator/=(const GNdarray &array)
Unary division operator.
Definition GNdarray.cpp:368
int dim(void) const
Return dimension of array.
Definition GNdarray.hpp:280
GNdarray & operator-=(const GNdarray &array)
Unary subtraction operator.
Definition GNdarray.cpp:401
void init_members(void)
Initialise class members.
Definition GNdarray.cpp:841
void free_members(void)
Delete class members.
Definition GNdarray.cpp:876
virtual ~GNdarray(void)
Destructor.
Definition GNdarray.cpp:224
GNdarray(void)
Void constructor.
Definition GNdarray.cpp:57
GNdarray & operator+=(const GNdarray &array)
Unary addition operator.
Definition GNdarray.cpp:322
std::vector< int > m_strides
Steps in each dimension when traversing array.
Definition GNdarray.hpp:137
GNdarray & operator=(const GNdarray &array)
Assignment operator.
Definition GNdarray.cpp:246
const std::vector< int > & shape(void) const
Return shape of array.
Definition GNdarray.hpp:308
int index(const std::vector< int > &i) const
Compute array element index.
Definition GNdarray.cpp:754
const std::vector< int > & strides(void) const
Return strides of array.
Definition GNdarray.hpp:322
bool has_same_shape(const GNdarray &array) const
Check if array has the same shape.
Definition GNdarray.cpp:889
double & at(const int &ix)
1-dimensional array element access with range checking
Definition GNdarray.hpp:335
std::vector< double > m_data
Array data.
Definition GNdarray.hpp:138
GNdarray * clone(void) const
Clone array.
Definition GNdarray.cpp:545
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508