Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GIDI_vector.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# Copyright 2019, Lawrence Livermore National Security, LLC.
4# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
5# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
6# SPDX-License-Identifier: MIT
7# <<END-copyright>>
8*/
9
10#include <stdio.h>
11
12#include "GIDI.hpp"
13
14namespace GIDI {
15
16/*! \class Vector
17 * This class stores a mathematical vector and has methods that perform several vector operations (e.g., addition, subtraction).
18 */
19
20/* *********************************************************************************************************//**
21 *
22 * @param a_size [in] Number of initial elements of the matrix. All elements are initialized to 0.
23 ***********************************************************************************************************/
24
25Vector::Vector( std::size_t a_size ) {
26
27 m_vector.resize( a_size, 0.0 );
28}
29
30/* *********************************************************************************************************//**
31 *
32 * @param a_values [in] A list of doubles to initialize *this* with.
33 ***********************************************************************************************************/
34
35Vector::Vector( std::vector<double> const &a_values ) {
36
37 m_vector = a_values;
38}
39
40/* *********************************************************************************************************//**
41 *
42 * @param a_number [in] This number of element pointed to by *a_values*.
43 * @param a_values [in] A list of doubles to initialize *this* with.
44 ***********************************************************************************************************/
45
46Vector::Vector( std::size_t a_number, double const *a_values ) {
47
48 m_vector.resize( a_number );
49 for( std::size_t i1 = 0; i1 < a_number; ++i1 ) m_vector[i1] = a_values[i1];
50}
51
52/* *********************************************************************************************************//**
53 *
54 * @param a_vector [in] Vector to copy.
55 ***********************************************************************************************************/
56
57Vector::Vector( Vector const &a_vector ) :
58 m_vector( a_vector.m_vector ) {
59
60}
61
62/* *********************************************************************************************************//**
63 * Returns a new Vector whose elements are *this* plus *a_rhs*.
64 *
65 * @param a_rhs [in] The value to add to each element.
66 * @return New Vectors whose elements are *this* plus *a_rhs*.
67 ***********************************************************************************************************/
68
70
71 if( this != &a_rhs ) {
72 m_vector = a_rhs.m_vector;
73 }
74
75 return( *this );
76}
77/*
78=========================================================
79*/
81
82}
83
84/* *********************************************************************************************************//**
85 * Returns a new Vector whose elements are *this* plus *a_value*.
86 *
87 * @param a_value [in] The value to add to each element.
88 * @return New Vector whose elements are *this* plus *a_value*.
89 ***********************************************************************************************************/
90
91Vector Vector::operator+( double a_value ) const {
92
93 Vector gidiVector( *this );
94
95 gidiVector += a_value;
96 return( gidiVector );
97}
98
99/* *********************************************************************************************************//**
100 * Adds *a_value* to each element of *this*.
101 *
102 * @param a_value [in] The value to add to each element.
103 * @return Returns reference to *this*.
104 ***********************************************************************************************************/
105
106Vector &Vector::operator+=( double a_value ) {
107
108 for( std::vector<double>::iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter ) *iter += a_value;
109
110 return( *this );
111}
112
113/* *********************************************************************************************************//**
114 * Adds two Vectors.
115 *
116 * @param a_rhs [in] Vector to add to *this*.
117 * @return New Vector that is the vector sum of *this* and *a_rhs*.
118 ***********************************************************************************************************/
119
120Vector Vector::operator+( Vector const &a_rhs ) const {
121
122 Vector gidiVector( *this );
123
124 gidiVector += a_rhs;
125 return( gidiVector );
126}
127
128/* *********************************************************************************************************//**
129 * Adds *a_rhs* to *this*.
130 *
131 * @param a_rhs [in] Vector to add to *this*.
132 * @return Returns reference to *this*.
133 ***********************************************************************************************************/
134
136
137 if( a_rhs.size( ) == 0 ) return( *this );
138
139 if( size( ) == 0 ) resize( a_rhs.size( ) );
140 if( size( ) != a_rhs.size( ) ) throw Exception( "vector sizes differ." );
141
142 std::size_t i1 = 0;
143 for( std::vector<double>::iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter, ++i1 ) *iter += a_rhs[i1];
144
145 return( *this );
146}
147
148/* *********************************************************************************************************//**
149 * Returns a new Vector whose elements are *this* minus *a_value*.
150 *
151 * @param a_value [in] The value to subtract from each element.
152 * @return New Vector whose elements are *this* plus *a_value*.
153 ***********************************************************************************************************/
154
155Vector Vector::operator-( double a_value ) const {
156
157 Vector gidiVector( *this );
158
159 gidiVector -= a_value;
160 return( gidiVector );
161}
162
163/* *********************************************************************************************************//**
164 * Subtracts *a_value* from each element of *this*.
165 *
166 * @param a_value [in] The value to subtract from each element.
167 * @return Returns reference to *this*.
168 ***********************************************************************************************************/
169
170Vector &Vector::operator-=( double a_value ) {
171
172 for( std::vector<double>::iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter ) *iter -= a_value;
173
174 return( *this );
175}
176
177/* *********************************************************************************************************//**
178 * Subtracts *a_rhs* from *this*.
179 *
180 * @param a_rhs [in] Vector to subtract from *this*.
181 * @return New Vector that is *this* minus *a_rhs*.
182 ***********************************************************************************************************/
183
184Vector Vector::operator-( Vector const &a_rhs ) const {
185
186 Vector gidiVector( *this );
187
188 gidiVector -= a_rhs;
189 return( gidiVector );
190}
191
192/* *********************************************************************************************************//**
193 * Subtracts *a_rhs* to *this*.
194 *
195 * @param a_rhs [in] Vector to subtract from *this*.
196 * @return Returns reference to *this*.
197 ***********************************************************************************************************/
198
200
201 if( a_rhs.size( ) == 0 ) return( *this );
202
203 if( size( ) == 0 ) resize( a_rhs.size( ) );
204 if( size( ) != a_rhs.size( ) ) throw Exception( "vector sizes differ." );
205
206 std::size_t i1 = 0;
207 for( std::vector<double>::iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter, ++i1 ) *iter -= a_rhs[i1];
208
209 return( *this );
210}
211
212/* *********************************************************************************************************//**
213 * Returns a new Vector whose elements are *this* multiplied by *a_value*.
214 *
215 * @param a_value [in] The value to multiply each element by.
216 * @return New Vector whose elements are *this* multiply by *a_value*.
217 ***********************************************************************************************************/
218
219Vector Vector::operator*( double a_value ) const {
220
221 Vector gidiVector( *this );
222
223 gidiVector *= a_value;
224 return( gidiVector );
225}
226
227/* *********************************************************************************************************//**
228 * Multiplies each element of *this* by *a_value*.
229 *
230 * @param a_value [in] The value to multiply each element by.
231 * @return Returns reference to *this*.
232 ***********************************************************************************************************/
233
234Vector &Vector::operator*=( double a_value ) {
235
236 for( std::vector<double>::iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter ) *iter *= a_value;
237
238 return( *this );
239}
240
241/* *********************************************************************************************************//**
242 * Returns a new Vector whose elements are *this* divided by *a_value*.
243 *
244 * @param a_value [in] The value to divide each element by.
245 * @return New Vector whose elements are *this* divided by *a_value*.
246 ***********************************************************************************************************/
247
248Vector Vector::operator/( double a_value ) const {
249
250 Vector gidiVector( *this );
251
252 gidiVector /= a_value;
253 return( gidiVector );
254}
255
256/* *********************************************************************************************************//**
257 * Divides each element of *this* by *a_value*.
258 *
259 * @param a_value [in] The value to divide each element by.
260 * @return Returns reference to *this*.
261 ***********************************************************************************************************/
262
263Vector &Vector::operator/=( double a_value ) {
264
265 if( a_value == 0 ) throw Exception( "divide by zero." );
266 for( std::vector<double>::iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter ) *iter /= a_value;
267
268 return( *this );
269}
270
271/* *********************************************************************************************************//**
272 * Reverse the elements of *this*.
273 ***********************************************************************************************************/
274
276
277 std::size_t i2 = size( ), n_2 = i2 / 2;
278
279 --i2;
280 for( std::size_t i1 = 0; i1 < n_2; ++i1, --i2 ) {
281 double temp = m_vector[i1];
282
283 m_vector[i1] = m_vector[i2];
284 m_vector[i2] = temp;
285 }
286}
287
288/* *********************************************************************************************************//**
289 * Sets all elements in the range [*a_start*,*a_end*) to *a_value*.
290 *
291 * @param a_start [in] The starting flat-cell index of *this* to fill with *a_value*.
292 * @param a_end [in] One after the last flat-cell index of *this* to fill with *a_value*.
293 * @param a_value [in] The value to set each double in the range to.
294 ***********************************************************************************************************/
295
296void Vector::setToValueInFlatRange( std::size_t a_start, std::size_t a_end, double a_value ) {
297
298 a_end = std::min( a_end, m_vector.size( ) );
299 for( ; a_start < a_end; ++a_start ) m_vector[a_start] = a_value;
300}
301/* *********************************************************************************************************//**
302 * Returns the sum over the values of *this*.
303 ***********************************************************************************************************/
304
305double Vector::sum( ) {
306
307 double sum1 = 0.0;
308
309 for( std::size_t i1 = 0; i1 < size( ); ++i1 ) sum1 += m_vector[i1];
310
311 return( sum1 );
312}
313
314/* *********************************************************************************************************//**
315 * Prints the contents of *this* to std::cout as one line prefixed with **a_prefix**.
316 *
317 * @param a_prefix [in] Prefix to add to line.
318 ***********************************************************************************************************/
319
320void Vector::print( std::string const &a_prefix ) const {
321
322 std::cout << a_prefix;
323 for( std::vector<double>::const_iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter ) printf( "%19.11e", *iter );
324 std::cout << std::endl;
325}
326
327/* *********************************************************************************************************//**
328 * Writes the contents of *this* to *a_file* as one line prefixed with **a_prefix**.
329 *
330 * @param a_file [in] A pointer to an opened C FILE instance where the data are to be written.
331 * @param a_prefix [in] Prefix to add to line.
332 ***********************************************************************************************************/
333
334void Vector::write( FILE *a_file, std::string const &a_prefix ) const {
335
336 if( a_prefix.size( ) > 0 ) fprintf( a_file, "# %s\n", a_prefix.c_str( ) );
337 for( std::vector<double>::const_iterator iter = m_vector.begin( ); iter < m_vector.end( ); ++iter ) fprintf( a_file, "%19.11e\n", *iter );
338}
339
340/* *********************************************************************************************************//**
341 * This method writes the contents of *this* to output *a_file* with each pair (boundary, value) as one line. Each line is written
342 * with the C *printf* style format as specified via the *a_format* arguement. If *a_epsilon* is zero then ( size() + 1 )
343 * lines are printed with the last y-value being the last value in *this*. If *a_epsilon* is not zero then ( 2 * size() )
344 * lines are printed with each boundary with index 1 to size() being print at first ( boundary[index] * ( 1 - a_epsilon ) )
345 * and then ( boundary[index] * ( 1 + a_epsilon ) ) as :
346 *
347 * boundary[index] * ( 1 - a_epsilon ) ), this[index-1]
348 * boundary[index] * ( 1 + a_epsilon ) ), this[index]
349 *
350 *
351 * @param a_file [in] A pointer to an opened C FILE instance where the data are to be written.
352 * @param a_format [in] A C *printf* style format to wrint one line of each (boundary, value) pair. Must include the line feed character.
353 * @param a_boundaries [in] The list of boundaries. Must contain (size() + 1) values except for the case when size() is 0.
354 * @param a_epsilon [in] Prefix to add to line.
355 ***********************************************************************************************************/
356
357void Vector::writeWithBoundaries( FILE *a_file, char const *a_format, std::vector<double> const &a_boundaries, double a_epsilon ) const {
358
359 if( size( ) == 0 ) {
360 if( a_boundaries.size( ) > 0 ) {
361 Vector vector( a_boundaries.size( ) - 1 );
362 vector.writeWithBoundaries2( a_file, a_format, a_boundaries, a_epsilon ); } }
363 else {
364 if( size( ) + 1 != a_boundaries.size( ) ) throw Exception( "Vector::writeWithBoundaries: Vector size and number of boundaries are not compatible." );
365 writeWithBoundaries2( a_file, a_format, a_boundaries, a_epsilon );
366 }
367}
368
369/* *********************************************************************************************************//**
370 * For internal use only. See method **writeWithBoundaries** for description.
371 *
372 * @param a_file [in] A pointer to an opened C FILE instance where the data are to be written.
373 * @param a_format [in] A C *printf* style format to wrint one line of each (boundary, value) pair. Do not include the line feed character.
374 * @param a_boundaries [in] The list of boundaries. Must contain (size() + 1) values except for the case when size() is 0.
375 * @param a_epsilon [in] Prefix to add to line.
376 ***********************************************************************************************************/
377void Vector::writeWithBoundaries2( FILE *a_file, char const *a_format, std::vector<double> const &a_boundaries, double a_epsilon ) const {
378
379 std::size_t numberOfValues = size( );
380
381 if( a_epsilon == 0.0 ) {
382 for( std::size_t index = 0; index < numberOfValues; ++index ) fprintf( a_file, a_format, a_boundaries[index], m_vector[index] ); }
383 else {
384 if( numberOfValues > 0 ) fprintf( a_file, a_format, a_boundaries[0], m_vector[0] );
385 for( std::size_t index = 1; index < numberOfValues; ++index ) {
386 fprintf( a_file, a_format, a_boundaries[index] * ( 1.0 - a_epsilon ), m_vector[index-1] );
387
388 fprintf( a_file, a_format, a_boundaries[index] * ( 1.0 + a_epsilon ), m_vector[index] );
389 }
390 }
391 if( numberOfValues > 0 ) fprintf( a_file, a_format, a_boundaries[numberOfValues], m_vector[numberOfValues-1] );
392}
393
394}
Vector & operator+=(double a_value)
Vector operator+(double a_value) const
Vector & operator*=(double a_value)
std::size_t size() const
Definition GIDI_data.hpp:79
Vector operator/(double a_value) const
void setToValueInFlatRange(std::size_t a_start, std::size_t a_end, double a_value)
Vector & operator=(Vector const &a_rhs)
void writeWithBoundaries(FILE *a_file, char const *a_format, std::vector< double > const &a_boundaries, double a_epsilon) const
Vector & operator-=(double a_value)
void write(FILE *a_file, std::string const &a_prefix) const
Vector & operator/=(double a_value)
void print(std::string const &a_prefix) const
Vector operator-(double a_value) const
Vector(std::size_t a_number=0)
void resize(std::size_t a_number, double a_value=0.0)
Definition GIDI_data.hpp:80
Vector operator*(double a_value) const
Definition GIDI.hpp:32