4
// Copyright (c) 1998-2010 by The VoxBo Development Team
6
// This file is part of VoxBo
8
// VoxBo is free software: you can redistribute it and/or modify it
9
// under the terms of the GNU General Public License as published by
10
// the Free Software Foundation, either version 3 of the License, or
11
// (at your option) any later version.
13
// VoxBo is distributed in the hope that it will be useful, but
14
// WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
// General Public License for more details.
18
// You should have received a copy of the GNU General Public License
19
// along with VoxBo. If not, see <http://www.gnu.org/licenses/>.
21
// For general information on VoxBo, including the latest complete
22
// source code and binary distributions, manual, and associated files,
23
// see the VoxBo home page at: http://www.voxbo.org/
25
// original version written by Kosh Banerjee
26
// changes/additions by Dan Kimberg
31
#include <gsl/gsl_fit.h>
32
#include <gsl/gsl_statistics_double.h>
34
gsl_error_handler_t *VB_Vector::currentGSLErrorHandler = NULL;
36
VB_Vector::VB_Vector()
38
this->init(false, vb_double, "ref1");
39
this->theVector = NULL;
42
VB_Vector::VB_Vector(const size_t len)
44
this->init(false, vb_double, "ref1");
52
gsl_vector_free(this->theVector);
53
this->init(false, vb_double, "ref1");
62
for (int i=0; i<size(); i++)
63
printf(" %010d: %.8f\n",i,getElement(i));
67
VB_Vector::init(const size_t len) throw (GenericExcep)
70
gsl_vector_free(this->theVector);
73
this->theVector=gsl_vector_calloc(len);
74
if (this->theVector != NULL)
80
VB_Vector::init(const bool validFlag,const VB_datatype dType,const string signature)
82
init(validFlag,dType,findFileFormat(signature));
85
void VB_Vector::init(const bool validFlag, const VB_datatype dType, const VBFF fType)
87
this->valid = validFlag;
88
this->dataType = dType;
89
this->fileFormat = fType;
92
/*********************************************************************
93
* This method allocates memory to the input gsl_matrix struct. *
94
*********************************************************************/
95
gsl_matrix *VB_Vector::initMatrix(const size_t rows, const size_t cols) const throw (GenericExcep)
98
/*********************************************************************
99
* Allocating the required memory to m. All elements of m will be *
100
* initialized to 0. *
101
*********************************************************************/
102
gsl_matrix *m = gsl_matrix_calloc(rows, cols);
104
/*********************************************************************
105
* If m is null, then we were unsuccessful in allocating memory for *
106
* it. Therefore, a GenericExcep is thrown. *
107
*********************************************************************/
110
/*********************************************************************
111
* errorMsg[] will hold an appropriate error message. *
112
*********************************************************************/
113
char errorMsg[OPT_STRING_LENGTH];
114
memset(errorMsg, 0, OPT_STRING_LENGTH);
116
/*********************************************************************
117
* Populating errorMsg[] with the appropriate error message. *
118
*********************************************************************/
119
sprintf(errorMsg, "The requested matrix size [%d x %d] could not be allocated.",
120
(int)rows, (int)cols);
122
/*********************************************************************
123
* Now throwing the exception. *
124
*********************************************************************/
125
throw GenericExcep(__LINE__, __FILE__, __FUNCTION__,
130
/*********************************************************************
131
* Now returning the address of the allocated gsl_matrix struct. *
132
*********************************************************************/
135
} // gsl_matrix *VB_Vector::initMatrix(const size_t rows, const size_t cols) const throw (GenericExcep)
137
/*********************************************************************
138
* This private method is used as a wrapper around gsl_vector_memcpy()*
139
* to enable throwing an exception (if necessary). *
140
*********************************************************************/
141
void VB_Vector::GSLVectorMemcpy(gsl_vector *dest, const gsl_vector *src) const throw (GenericExcep)
144
/*********************************************************************
145
* gsl_vector_memcpy() is called to copy src to dest . It's return *
146
* value will be processed by VB_Vector::checkGSLStatus() and if the *
147
* return value is non-zero, then VB_Vector::checkGSLStatus() will *
148
* throw (and catch) an exception with an appropriate error message *
149
* (as returned by gsl_strerror()). *
150
*********************************************************************/
151
VB_Vector::checkGSLStatus(gsl_vector_memcpy(dest, src), __LINE__, __FILE__, __FUNCTION__);
153
} // void VB_Vector::GSLVectorMemcpy(gsl_vector *dest, const gsl_vector *src) const throw (GenericExcep)
155
/*********************************************************************
156
* This private method throws an exception if the input index is not *
157
* within the range of the length of this instance of VB_Vector. *
158
*********************************************************************/
159
void VB_Vector::checkVectorRange(const size_t index, const int lineNumber, const char *fileName, const char *prettyFunctionName) const throw (GenericExcep)
162
/*********************************************************************
163
* If the index is out of range of the vector length, then an *
164
* exception is thrown. *
165
*********************************************************************/
166
if (index >= this->getLength())
169
/*********************************************************************
170
* errorMsg[] will hold the error message that the index is out of *
172
*********************************************************************/
173
char errorMsg[OPT_STRING_LENGTH];
174
memset(errorMsg, 0, OPT_STRING_LENGTH);
176
/*********************************************************************
177
* Populating errorMsg[] with the appropriate error message. *
178
*********************************************************************/
179
sprintf(errorMsg, "The index [%d] is not in the vector range [0, %d].",
180
(int)index, (int)(this->getLength() - 1));
182
/*********************************************************************
183
* Now throwing the exception. *
184
*********************************************************************/
185
throw GenericExcep(lineNumber, fileName, prettyFunctionName, errorMsg);
189
} // void VB_Vector::checkVectorRange(const size_t index, const int lineNumber, const char *fileName, const char *prettyFunctionName) const throw (GenericExcep)
191
/*********************************************************************
192
* This private static method throws an exception if the lengths of *
193
* the 2 input gsl_vector structs are not equal. *
194
*********************************************************************/
195
void VB_Vector::checkVectorLengths(const gsl_vector *V1, const gsl_vector *V2, const int lineNumber, const char *fileName, const char *prettyFunctionName) throw (GenericExcep)
198
/*********************************************************************
199
* We now check to see that we don't have a NULL gsl_vector. If either*
200
* gsl_vector argument is NULL, then an exception is thrown with an *
201
* appropriate error message. *
202
*********************************************************************/
203
if ( V1==NULL || V2==NULL )
205
ostringstream errorMsg;
206
errorMsg << "Have a NULL gsl_vector in [" << __FUNCTION__ << "].";
207
throw GenericExcep(lineNumber, fileName, prettyFunctionName, errorMsg.str());
210
/*********************************************************************
211
* If the vector lengths do no match, then an exception is thrown. *
212
*********************************************************************/
213
if (V1->size != V2->size)
216
/*********************************************************************
217
* errorMsg[] will hold the error message that the vector lengths are *
219
*********************************************************************/
220
char errorMsg[OPT_STRING_LENGTH];
221
memset(errorMsg, 0, OPT_STRING_LENGTH);
223
/*********************************************************************
224
* Populating errorMsg[] with the appropriate error message. *
225
*********************************************************************/
226
sprintf(errorMsg, "Unequal vector lengths: [%d] and [%d]",
227
(int)(V1->size), (int)(V2->size));
229
/*********************************************************************
230
* Now throwing the exception. *
231
*********************************************************************/
232
throw GenericExcep(lineNumber, fileName, prettyFunctionName, errorMsg);
236
} // void VB_Vector::checkVectorLengths(const gsl_vector *V1, const gsl_vector *V2, const int lineNumber, const char *fileName, const char *prettyFunctionName) throw (GenericExcep)
238
/*********************************************************************
239
* This private static method throws an exception if the two input *
240
* size_t variables, len1 and len2, are not equal. *
241
*********************************************************************/
242
void VB_Vector::checkVectorLengths(const size_t len1, const size_t len2, const int lineNumber, const char *fileName, const char *prettyFunctionName) throw (GenericExcep)
245
/*********************************************************************
246
* If the vectors length do no match, then an exception is thrown. *
247
*********************************************************************/
251
/*********************************************************************
252
* errorMsg[] will hold the error message that the vector lengths are *
254
*********************************************************************/
255
char errorMsg[OPT_STRING_LENGTH];
256
memset(errorMsg, 0, OPT_STRING_LENGTH);
258
/*********************************************************************
259
* Populating errorMsg[] with the appropriate error message. *
260
*********************************************************************/
261
sprintf(errorMsg, "Unequal vector lengths: [%d] and [%d]",
262
(int)len1, (int)len2);
264
/*********************************************************************
265
* Now throwing the exception. *
266
*********************************************************************/
267
throw GenericExcep(lineNumber, fileName, prettyFunctionName, errorMsg);
271
} // void VB_Vector::checkVectorLengths(const size_t len1, const size_t len2, const int lineNumber, const char *fileName, const char *prettyFunctionName) throw (GenericExcep)
273
/*********************************************************************
274
* This private static method throws a GenericExcep if the input *
275
* gsl_vector struct is null. *
276
*********************************************************************/
277
void VB_Vector::vectorNull(const gsl_vector *v) throw (GenericExcep)
280
/*********************************************************************
281
* If the input gsl_vector struct is null, then the exception is *
283
*********************************************************************/
286
throw GenericExcep(__LINE__, __FILE__, __FUNCTION__,
287
"ERROR: Unable to allocate memory for VB_Vector.");
290
} // void VB_Vector::vectorNull(const gsl_vector *v) throw (GenericExcep)
292
/*********************************************************************
293
* This private static method throws a GenericExcep and catches it *
294
* if the input variable status is non-zero. This method should be *
295
* called after a GSL function returns its status. *
296
*********************************************************************/
297
void VB_Vector::checkGSLStatus(const int status, const int lineNumber, const char *fileName, const char *prettyFunctionName)
300
/*********************************************************************
301
* If status is non-zero, then try/catch blocks are used to throw a *
302
* GenericExcep and then process it. *
303
*********************************************************************/
308
throw GenericExcep(lineNumber, fileName, prettyFunctionName,
309
gsl_strerror(status));
311
catch (GenericExcep &e)
313
e.whatNoExit(lineNumber, fileName, prettyFunctionName);
317
} // void VB_Vector::checkGSLStatus(const int status, const int lineNumber, const char *fileName, const char *prettyFunctionName)
319
/*********************************************************************
320
* This private static method throws a GenericExcep and catches it *
321
* if the input variable norm is zero. *
322
*********************************************************************/
323
void VB_Vector::zeroVector(const double norm, const int lineNumber, const char *fileName, const char *prettyFunctionName)
326
/*********************************************************************
327
* If norm is zero, then try/catch blocks are used to throw a *
328
* GenericExcep and then process it. *
329
*********************************************************************/
334
throw GenericExcep(lineNumber, fileName, prettyFunctionName,
335
"The vector is a zero vector.");
337
catch (GenericExcep &e)
339
e.whatNoExit(lineNumber, fileName, prettyFunctionName);
343
} // void VB_Vector::zeroVector(const double norm, const int lineNumber, const char *fileName, const char *prettyFunctionName)
345
/*********************************************************************
346
* This static method throws and catches an exception of type *
348
*********************************************************************/
349
void VB_Vector::createException(const char *errorMsg, const int lineNumber, const char *fileName, const char *prettyFunctionName)
352
/*********************************************************************
353
* Now throwing and catching the exception. *
354
*********************************************************************/
357
throw GenericExcep(lineNumber, fileName, prettyFunctionName, errorMsg);
359
catch (GenericExcep &e)
361
e.whatNoExit(lineNumber, fileName, prettyFunctionName);
364
} // void VB_Vector::createException(const char *errorMsg, const int lineNumber, const char *fileName, const char *prettyFunctionName)
366
/*********************************************************************
367
* This static method throws and catches an exception of type *
369
*********************************************************************/
370
void VB_Vector::createException(const string& errorMsg, const int lineNumber, const string& fileName, const string& prettyFunctionName)
373
/*********************************************************************
374
* Now throwing the exception. *
375
*********************************************************************/
376
VB_Vector::createException(errorMsg.c_str(), lineNumber, fileName.c_str(), prettyFunctionName.c_str());
378
} // void VB_Vector::createException(const string& errorMsg, const int lineNumber, const string& fileName, const string& prettyFunctionName)
380
/*********************************************************************
381
* This static method will call VB_Vector::createException() if any *
382
* elements of the input gsl_struct are Inf or Nan. *
383
*********************************************************************/
384
void VB_Vector::checkFiniteness(const gsl_vector *v, const int lineNumber, const char *fileName, const char *prettyFunctionName)
387
/*********************************************************************
388
* The following for loop is used to examine each element of the *
389
* input gsl_vector struct. *
390
*********************************************************************/
391
for (size_t i = 0; i < v->size; i++)
394
/*********************************************************************
395
* If the input double to gsl_finite() is an Inf or a Nan, then *
396
* gsl_finite() will return 0. Otherwise, 1 is returned. *
397
*********************************************************************/
398
if (!gsl_finite(v->data[i]))
401
/*********************************************************************
402
* errorMsg[] will hold the error message that an Inf or Nan was *
404
*********************************************************************/
405
char errorMsg[OPT_STRING_LENGTH];
406
memset(errorMsg, 0, OPT_STRING_LENGTH);
408
/*********************************************************************
409
* Populating errorMsg[] with the appropriate error message. *
410
*********************************************************************/
411
sprintf(errorMsg, "The vector element at index [%d] is an Inf or a NaN.", (int)i);
413
/*********************************************************************
414
* Now VB_Vector::createException() is called to trhow and catch a *
415
* GenericExcep so that an appropriate error message gets displayed. *
416
*********************************************************************/
417
VB_Vector::createException(errorMsg, lineNumber, fileName, prettyFunctionName);
419
/*********************************************************************
420
* We now break from the for loop since we have found at least 1 Inf *
422
*********************************************************************/
429
} // void VB_Vector::checkFiniteness(const gsl_vector *v, const int lineNumber, const char *fileName, const char *prettyFunctionName)
431
/*********************************************************************
432
* This constructor uses the input variable len as the length of the *
433
* the vector and the input variable data as the elements of the *
434
* vector. NOTE: Is is expected that data is an array of doubles whose*
436
*********************************************************************/
437
VB_Vector::VB_Vector(const double *data, const size_t len)
440
/*********************************************************************
441
* Setting this->valid, this->dataType, and this->fileFormat. *
442
*********************************************************************/
443
this->init(false, vb_double, "ref1");
445
/*********************************************************************
446
* We call this->init() and catch its exception, if one is thrown. *
447
*********************************************************************/
452
catch (GenericExcep &e)
454
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
457
/*********************************************************************
458
* Now copying the values from data to this->theVector->data. *
459
*********************************************************************/
460
memcpy(this->theVector->data, data, this->theVector->size * sizeof(double));
462
} // VB_Vector::VB_Vector(const double *data, const size_t len)
464
/*********************************************************************
465
* This constructor builds a VB_Vector from the input gsl_vector *
467
*********************************************************************/
468
VB_Vector::VB_Vector(const gsl_vector *V2)
471
/*********************************************************************
472
* Setting this->fileName, this->valid, this->dataType, and *
473
* this->fileFormat. Since we don't have an actual file name, a *
474
* temporary file name is used. *
475
*********************************************************************/
476
char tmpFileName[STRINGLEN];
477
memset(tmpFileName, 0, STRINGLEN);
478
strcpy(tmpFileName, "./tmp-");
479
this->init(false, vb_double, "ref1");
481
/*********************************************************************
482
* Setting this->theVector to NULL. *
483
*********************************************************************/
484
this->theVector = NULL;
486
/*********************************************************************
487
* We call this->init() and catch its exception, if one is thrown. *
488
*********************************************************************/
492
/*********************************************************************
493
* Allocating a gsl_vector struct and all the elements will be set to *
495
*********************************************************************/
496
this->init(V2->size);
499
catch (GenericExcep &e)
501
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
504
/*********************************************************************
505
* Now copying the values from V2.data to this->theVector->data. The *
506
* try/catch blocks are used to process the exception, if one is *
508
*********************************************************************/
511
this->GSLVectorMemcpy(this->theVector, V2);
513
catch (GenericExcep &e)
515
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
518
} // VB_Vector::VB_Vector(const gsl_vector *V2)
520
/*********************************************************************
521
* This constructor builds a VB_Vector from the input gsl_vector *
523
*********************************************************************/
524
VB_Vector::VB_Vector(const gsl_vector& V2)
527
/*********************************************************************
528
* Setting this->valid, this->dataType, and this->fileFormat. *
529
*********************************************************************/
530
this->init(false, vb_double, "ref1");
532
/*********************************************************************
533
* Setting this->theVector to NULL. *
534
*********************************************************************/
535
this->theVector = NULL;
537
/*********************************************************************
538
* We call this->init() and catch its exception, if one is thrown. *
539
*********************************************************************/
543
/*********************************************************************
544
* Allocating a gsl_vector struct and all the elements will be set to *
546
*********************************************************************/
549
catch (GenericExcep &e)
551
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
554
/*********************************************************************
555
* Now copying the values from V2.data to this->theVector->data. The *
556
* try/catch blocks are used to process the exception, if one is *
558
*********************************************************************/
561
this->GSLVectorMemcpy(this->theVector, &V2);
563
catch (GenericExcep &e)
565
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
568
} // VB_Vector::VB_Vector(const gsl_vector& V2)
570
/*********************************************************************
571
* This is the copy constructor. *
572
*********************************************************************/
573
VB_Vector::VB_Vector(const VB_Vector& V2)
576
/*********************************************************************
577
* Setting this->valid, this->dataType, and this->fileFormat. *
578
*********************************************************************/
579
this->init(false, V2.dataType,V2.fileFormat);
581
/*********************************************************************
582
* Setting this->fileName to V2.fileName. *
583
*********************************************************************/
584
this->fileName = V2.fileName;
586
/*********************************************************************
587
* We call this->init() and catch its exception, if one is thrown. *
588
*********************************************************************/
592
/*********************************************************************
593
* If V2.theVector is not null, then a gsl_vector struct is allocated *
594
* and all the elements of this->theVector->data[] will be set to 0. *
595
* Otherwise, this->theVector is set to NULL. *
596
*********************************************************************/
599
this->init(V2.theVector->size);
601
/*********************************************************************
602
* Now copying the values from V2.theVector to this->theVector. The *
603
* try/catch blocks are used to process the exception, if one is *
605
*********************************************************************/
608
this->GSLVectorMemcpy(this->theVector, V2.theVector);
610
catch (GenericExcep &e)
612
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
618
this->theVector = NULL;
622
catch (GenericExcep &e)
624
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
627
} // VB_Vector::VB_Vector(const VB_Vector& V2)
629
/*********************************************************************
630
* This constructor instantiates a VB_Vector from the input VBVector *
632
*********************************************************************/
633
VB_Vector::VB_Vector(const VB_Vector *V)
636
/*********************************************************************
637
* Setting this->valid, this->dataType, and this->fileFormat. *
638
*********************************************************************/
639
this->init(false, V->dataType,V->fileFormat);
641
/*********************************************************************
642
* Setting this->fileName to V->fileName. *
643
*********************************************************************/
644
this->fileName = V->fileName;
646
/*********************************************************************
647
* We call this->init() and catch its exception, if one is thrown. *
648
*********************************************************************/
652
/*********************************************************************
653
* If V->theVector is not null, then a gsl_vector struct is allocated *
654
* and all the elements of this->theVector->data[] will be set to 0. *
655
* Otherwise, this->theVector is set to NULL. *
656
*********************************************************************/
659
this->init(V->theVector->size);
663
this->theVector = NULL;
667
catch (GenericExcep &e)
669
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
672
/*********************************************************************
673
* Now copying the values from V->theVector to this->theVector. The *
674
* try/catch blocks are used to process the exception, if one is *
676
*********************************************************************/
679
this->GSLVectorMemcpy(this->theVector, V->theVector);
681
catch (GenericExcep &e)
683
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
686
} // VB_Vector::VB_Vector(const VB_Vector *V)
688
/*********************************************************************
689
* Constructor to read in a vector from a VoxBo vector file. *
690
*********************************************************************/
691
VB_Vector::VB_Vector(const string& vecFile)
694
/*********************************************************************
695
* Setting this->valid, this->dataType, and this->fileFormat. *
696
*********************************************************************/
697
this->init(false, vb_double, "ref1");
699
/*********************************************************************
700
* Reading the VoxBo vector file. *
701
*********************************************************************/
702
if (this->ReadFile(vecFile))
704
ostringstream errorMsg;
705
errorMsg << "[" << __FUNCTION__ << "]: Unable to read the file [" << vecFile << "].";
706
printErrorMsg(VB_WARNING, errorMsg.str());
709
} // VB_Vector::VB_Vector(const string& vecFile)
711
/*********************************************************************
712
* Constructor to read in a vector from a VoxBo vector file. *
713
*********************************************************************/
714
VB_Vector::VB_Vector(const char *vecFile)
717
/*********************************************************************
718
* Setting this->valid, this->dataType, and this->fileFormat. *
719
*********************************************************************/
720
this->init(false, vb_double, "ref1");
722
/*********************************************************************
723
* Setting this->fileName. *
724
*********************************************************************/
725
this->fileName = vecFile;
727
/*********************************************************************
728
* Reading the VoxBo vector file. *
729
*********************************************************************/
730
if (this->ReadFile(vecFile))
732
ostringstream errorMsg;
733
errorMsg << "[" << __FUNCTION__ << "]: Unable to read the file [" << vecFile << "].";
734
printErrorMsg(VB_WARNING, errorMsg.str());
737
} // VB_Vector::VB_Vector(const char *vecFile)
739
/*********************************************************************
740
* This constructor creates an instance of VB_Vector from a *
741
* reference to a vector <double>. *
742
*********************************************************************/
743
VB_Vector::VB_Vector(const vector<double>& theVector)
746
/*********************************************************************
747
* Now setting this->valid (to false), this->dataType, and *
748
* this->fileFormat. Also, this->fileName will be set to temporary file *
750
*********************************************************************/
751
this->init(false, vb_double, "ref1");
753
/*********************************************************************
754
* We call this->init() and catch its exception, if one is thrown. *
755
*********************************************************************/
758
this->init(theVector.size());
760
catch (GenericExcep &e)
762
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
765
/*********************************************************************
766
* Now the elements from theVector are copied to this->theVector. *
767
*********************************************************************/
768
copy(theVector.begin(), theVector.end(), this->theVector->data);
770
} // VB_Vector::VB_Vector(const vector<double>& theVector)
772
/*********************************************************************
773
* This constructor creates an instance of VB_Vector from a *
774
* pointer to a vector <double>. *
775
*********************************************************************/
776
VB_Vector::VB_Vector(const vector<double> *theVector)
779
/*********************************************************************
780
* Now setting this->valid (to false), this->dataType, and *
781
* this->fileFormat. Also, this->fileName will be set to temporary *
783
*********************************************************************/
784
this->init(false, vb_double, "ref1");
786
/*********************************************************************
787
* We call this->init() and catch its exception, if one is thrown. *
788
*********************************************************************/
791
this->init(theVector->size());
793
catch (GenericExcep &e)
795
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
798
/*********************************************************************
799
* Now the elements from theVector are copied to this->theVector. *
800
*********************************************************************/
801
copy(theVector->begin(), theVector->end(), this->theVector->data);
803
} // VB_Vector::VB_Vector(const vector<double> *theVector)
805
/*********************************************************************
806
* This constructor builds a VB_Vector from a pointer to a Vec. *
807
*********************************************************************/
808
VB_Vector::VB_Vector(const Vec *theVector)
811
/*********************************************************************
812
* Now setting this->valid (to false), this->dataType, and *
813
* this->fileFormat. Also, this->fileName will be set to temporary *
815
*********************************************************************/
816
this->init(false, vb_double, "ref1");
818
/*********************************************************************
819
* We call this->init() and catch its exception, if one is thrown. *
820
*********************************************************************/
823
this->init(theVector->size());
825
catch (GenericExcep &e)
827
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
830
/*********************************************************************
831
* Now the elements from theVector are copied to this->theVector. *
832
*********************************************************************/
833
memcpy(this->theVector->data, theVector->data, sizeof(double) * theVector->size());
835
} // VB_Vector::VB_Vector(const Vec *theVector)
837
/*********************************************************************
838
* This constructor builds a VB_Vector from a reference to a Vec. *
839
*********************************************************************/
840
VB_Vector::VB_Vector(const Vec& theVector)
843
/*********************************************************************
844
* Now setting this->valid (to false), this->dataType, and *
845
* this->fileFormat. Also, this->fileName will be set to temporary *
847
*********************************************************************/
848
this->init(false, vb_double, "ref1");
850
/*********************************************************************
851
* We call this->init() and catch its exception, if one is thrown. *
852
*********************************************************************/
855
this->init(theVector.size());
857
catch (GenericExcep &e)
859
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
862
/*********************************************************************
863
* Now the elements from theVector are copied to this->theVector. *
864
*********************************************************************/
865
memcpy(this->theVector->data, theVector.data, sizeof(double) * theVector.size());
867
} // VB_Vector::VB_Vector(const Vec& theVector)
869
/*********************************************************************
870
* This constructor is used to quickly generate a VB_Vector object *
871
* from the time series stored at the specified index. *
872
*********************************************************************/
873
VB_Vector::VB_Vector(const Tes& theTes, const unsigned long tSeriesIndex)
876
/*********************************************************************
877
* Setting this->valid, this->dataType, and this->fileFormat. *
878
*********************************************************************/
879
this->init(false, vb_double, "ref1");
881
/*********************************************************************
882
* We call this->init() and catch its exception, if one is thrown. *
883
*********************************************************************/
886
this->init(theTes.dimt);
888
catch (GenericExcep &e)
890
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
893
/*********************************************************************
894
* If theTes.data[tSeriesIndex] is not NULL, then it holds a *
895
* non-zero time series. NOTE: If in fact theTes.data[tSeriesIndex] *
896
* is NULL, then we have a time series that is entirely zero. *
897
* Therefore, we do not need to do anything else since the above call *
898
* to this->init() sets all the elements to 0. *
899
*********************************************************************/
900
if (theTes.data[tSeriesIndex])
903
/*********************************************************************
904
* We now switch on the possible data types for theTes. *
905
*********************************************************************/
906
switch(theTes.datatype)
910
/*********************************************************************
911
* The following for loop assigns each element of this instance of *
913
*********************************************************************/
914
for (long i = 0; i < theTes.dimt; i++)
916
this->theVector->data[i] = *((unsigned char *) (theTes.data[tSeriesIndex] + (i * theTes.datasize)));
923
/*********************************************************************
924
* The following for loop assigns each element of this instance of *
926
*********************************************************************/
927
for (long i = 0; i < theTes.dimt; i++)
929
this->theVector->data[i] = *((int16 *) (theTes.data[tSeriesIndex] + (i * theTes.datasize)));
936
/*********************************************************************
937
* The following for loop assigns each element of this instance of *
939
*********************************************************************/
940
for (long i = 0; i < theTes.dimt; i++)
942
this->theVector->data[i] = *((int32 *) (theTes.data[tSeriesIndex] + (i * theTes.datasize)));
949
/*********************************************************************
950
* The following for loop assigns each element of this instance of *
952
*********************************************************************/
953
for (long i = 0; i < theTes.dimt; i++)
955
this->theVector->data[i] = *((float *) (theTes.data[tSeriesIndex] + (i * theTes.datasize)));
962
/*********************************************************************
963
* The following for loop assigns each element of this instance of *
965
*********************************************************************/
966
for (long i = 0; i < theTes.dimt; i++)
968
this->theVector->data[i] = *((double *) (theTes.data[tSeriesIndex] + (i * theTes.datasize)));
977
} // VB_Vector::VB_Vector(const Tes& theTes, const unsigned long tSeriesIndex)
979
/*********************************************************************
980
* Method to turn off the current GSL error handler. *
981
*********************************************************************/
982
void VB_Vector::turnOffGSLErrorHandler() const
984
VB_Vector::currentGSLErrorHandler = gsl_set_error_handler_off();
985
} // void VB_Vector::turnOffGSLErrorHandler() const
987
/*********************************************************************
988
* Method to restore the GSL error handler to *
989
* VB_Vector::->currentGSLErrorHandler. *
990
*********************************************************************/
991
void VB_Vector::restoreGSLErrorHandler() const
994
/*********************************************************************
995
* If VB_Vector::currentGSLErrorHandler is not null, then the GSL *
996
* error handler is restored to VB_Vector::currentGSLErrorHandler. *
997
*********************************************************************/
998
if (VB_Vector::currentGSLErrorHandler)
1000
gsl_set_error_handler(VB_Vector::currentGSLErrorHandler);
1003
} // void VB_Vector::restoreGSLErrorHandler() const
1005
/*********************************************************************
1007
*********************************************************************/
1008
VB_Vector::~VB_Vector()
1011
/*********************************************************************
1012
* If this->valid is true, then a gsl_vector struct was allocated to *
1013
* this->theVector. Therefore, we delete the memory. *
1014
*********************************************************************/
1017
gsl_vector_free(this->theVector);
1020
} // VB_Vector::~VB_Vector()
1022
/*********************************************************************
1023
* This method simply returns the specified element from the vector. *
1024
*********************************************************************/
1025
double VB_Vector::getElement(const size_t index) const
1028
/*********************************************************************
1029
* We now check to make sure that index is within *
1030
* [0, this->theVector->size - 1]. The try/catch blocks are used to *
1031
* process any exception, if one is thrown by *
1032
* this->checkVectorRange(). *
1033
*********************************************************************/
1036
this->checkVectorRange(index, __LINE__, __FILE__, __FUNCTION__);
1038
catch (GenericExcep &e)
1040
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1043
/*********************************************************************
1044
* Now returning the specified element value. *
1045
*********************************************************************/
1046
return gsl_vector_get(this->theVector, index);
1048
} // double VB_Vector::getElement(const size_t index) const
1050
/*********************************************************************
1051
* This method simply returns a pointer to the specified element. *
1052
* NOTE: This method makes it possible to change the value of the *
1053
* specified element by using the return pointer, i.e., a different *
1054
* value can be assigned to the pointer. *
1055
*********************************************************************/
1056
double *VB_Vector::getElementPtr(size_t index) const
1059
/*********************************************************************
1060
* We now check to make sure that index is within *
1061
* [0, this->theVector->size - 1]. The try/catch blocks are used to *
1062
* process any exception, if one is thrown by *
1063
* this->checkVectorRange(). *
1064
*********************************************************************/
1067
this->checkVectorRange(index, __LINE__, __FILE__, __FUNCTION__);
1069
catch (GenericExcep &e)
1071
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1074
/*********************************************************************
1075
* Calling gsl_vector_ptr() to return the pointer to the specified *
1077
*********************************************************************/
1078
return gsl_vector_ptr(this->theVector, index);
1080
} // double *VB_Vector::getElementPtr(size_t index) const
1082
/*********************************************************************
1083
* This method simply returns a constant pointer to the specified *
1084
* element. NOTE: This method does not allow the value of the *
1085
* specified element to be changed since it returns a constant *
1087
*********************************************************************/
1088
const double *VB_Vector::getElementConstPtr(const size_t index) const
1091
/*********************************************************************
1092
* We now check to make sure that index is within *
1093
* [0, this->theVector->size - 1]. The try/catch blocks are used to *
1094
* process any exception, if one is thrown by *
1095
* this->checkVectorRange(). *
1096
*********************************************************************/
1099
this->checkVectorRange(index, __LINE__, __FILE__, __FUNCTION__);
1101
catch (GenericExcep &e)
1103
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1106
/*********************************************************************
1107
* Calling gsl_vector_ptr() to return the pointer to the specified *
1109
*********************************************************************/
1110
return gsl_vector_ptr(this->theVector, index);
1112
} // const double *VB_Vector::getElementConstPtr(const size_t index)
1114
/*********************************************************************
1115
* This method sets the specified element to the specified value. *
1116
*********************************************************************/
1117
void VB_Vector::setElement(const size_t index, const double value)
1120
/*********************************************************************
1121
* We now check to make sure that index is within *
1122
* [0, this->theVector->size - 1]. The try/catch blocks are used to *
1123
* process any exception, if one is thrown by *
1124
* this->checkVectorRange(). *
1125
*********************************************************************/
1128
this->checkVectorRange(index, __LINE__, __FILE__, __FUNCTION__);
1130
catch (GenericExcep &e)
1132
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1135
/*********************************************************************
1136
* Calling gsl_vector_set() to set the specified element to the *
1137
* specified value. *
1138
*********************************************************************/
1139
gsl_vector_set(this->theVector, index, value);
1141
} // void VB_Vector::setElement(const size_t index, const double value)
1143
/*********************************************************************
1144
* This method simply calculates the Euclidean inner product of this *
1145
* instance of VB_Vector and the input VB_Vector, V2. *
1146
*********************************************************************/
1147
double VB_Vector::euclideanProduct(const VB_Vector& V2) const
1150
/*********************************************************************
1151
* Now returning the Euclidean inner product. *
1152
*********************************************************************/
1153
return this->euclideanProduct(V2.theVector);
1155
} // double VB_Vector::euclideanProduct(const VB_Vector& V2) const
1157
/*********************************************************************
1158
* This method simply calculates the Euclidean inner product of this *
1159
* instance of VB_Vector and the input VB_Vector, V2. *
1160
*********************************************************************/
1161
double VB_Vector::euclideanProduct(const VB_Vector *V2) const
1164
/*********************************************************************
1165
* Now returning the Euclidean inner product. *
1166
*********************************************************************/
1167
return this->euclideanProduct(V2->theVector);
1169
} // double VB_Vector::euclideanProduct(const VB_Vector *V2) const
1171
/*********************************************************************
1172
* This method simply calculates the Euclidean inner product of this *
1173
* instance of VB_Vector and the input gsl_vector struct, V2. *
1174
*********************************************************************/
1175
double VB_Vector::euclideanProduct(const gsl_vector& V2) const
1178
/*********************************************************************
1179
* Now returning the Euclidean inner product. *
1180
*********************************************************************/
1181
return this->euclideanProduct(&V2);
1183
} // double VB_Vector::euclideanProduct(const gsl_vector& V2) const
1185
/*********************************************************************
1186
* This method simply calculates the Euclidean inner product of this *
1187
* instance of VB_Vector and the input gsl_vector struct, V2. *
1188
*********************************************************************/
1189
double VB_Vector::euclideanProduct(const gsl_vector *V2) const
1192
/*********************************************************************
1193
* By default, if gsl_blas_ddot() has an error, the GSL error *
1194
* handler will be invoked, which calls abort(), creating a core dump.*
1195
* To forgo this behavior, the GSL error handler is turned off and *
1196
* the current error handler is stored in *
1197
* VB_Vector::currentGSLErrorHandler. This is accomplished by the *
1198
* call to this->turnOffGSLErrorHandler(). *
1199
*********************************************************************/
1200
this->turnOffGSLErrorHandler();
1202
/*********************************************************************
1203
* The following try/catch blocks are used to ensure that the vector *
1204
* lengths are equal. *
1205
*********************************************************************/
1208
VB_Vector::checkVectorLengths(this->theVector, V2, __LINE__, __FILE__, __FUNCTION__);
1210
catch (GenericExcep &e)
1212
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1215
/*********************************************************************
1216
* result will hold the Euclidean inner product. *
1217
*********************************************************************/
1218
double result = 0.0;
1220
/*********************************************************************
1221
* Calling gsl_blas_ddot() to compute the Eucliden inner product. *
1222
* It's return value will be processed by VB_Vector::checkGSLStatus() *
1223
* and if the return value is non-zero, then *
1224
* VB_Vector::checkGSLStatus() will throw (and catch) an exception *
1225
* with an appropriate error message (as returned by gsl_strerror()). *
1226
*********************************************************************/
1227
VB_Vector::checkGSLStatus(gsl_blas_ddot(this->theVector, V2, &result), __LINE__, __FILE__, __FUNCTION__);
1229
/*********************************************************************
1230
* We now restore the standard GSL error handler by calling *
1231
* this->restoreGSLErrorHandler(). *
1232
*********************************************************************/
1233
this->restoreGSLErrorHandler();
1235
/*********************************************************************
1236
* Returning the inner product. *
1237
*********************************************************************/
1240
} // double VB_Vector::euclideanProduct(const gsl_vector *V2) const
1242
/*********************************************************************
1243
* This static method calculates the Euclidean inner product of the *
1244
* 2 input gsl_vector structs. *
1245
*********************************************************************/
1246
double VB_Vector::euclideanProduct(const gsl_vector *V1, const gsl_vector *V2)
1249
/*********************************************************************
1250
* Checking to see if the 2 input gsl_vector structs have the same *
1252
*********************************************************************/
1255
VB_Vector::checkVectorLengths(V1, V2, __LINE__, __FILE__, __FUNCTION__);
1257
catch (GenericExcep &e)
1259
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1262
/*********************************************************************
1263
* result will hold the Euclidean inner product. *
1264
*********************************************************************/
1265
double result = 0.0;
1267
/*********************************************************************
1268
* Calling gsl_blas_ddot() to compute the Eucliden inner product. It's*
1269
* return value will be processed by VB_Vector::checkGSLStatus(). If *
1270
* the return value is non-zero, then VB_Vector::checkGSLStatus() will*
1271
* throw (and catch) an exception with an appropriate error message *
1272
* (as returned by gsl_strerror()). *
1273
*********************************************************************/
1274
VB_Vector::checkGSLStatus(gsl_blas_ddot(V1, V2, &result), __LINE__, __FILE__, __FUNCTION__);
1276
/*********************************************************************
1277
* Returning the Euclidean inner product. *
1278
*********************************************************************/
1281
} // double VB_Vector::euclideanProduct(const gsl_vector *V1, const gsl_vector *V2)
1283
/*********************************************************************
1284
* This static method calculates the Euclidean inner product of the *
1285
* 2 input gsl_vector structs. *
1286
*********************************************************************/
1287
double VB_Vector::euclideanProduct(const gsl_vector& V1, const gsl_vector& V2)
1290
/*********************************************************************
1291
* Calling VB_Vector::euclideanProduct(const gsl_vector *, *
1292
* const gsl_vector *) to return the Euclidean inner product. *
1293
*********************************************************************/
1294
return VB_Vector::euclideanProduct(&V1, &V2);
1296
} // double VB_Vector::euclideanProduct(const gsl_vector& V1, const gsl_vector& V2)
1298
/*********************************************************************
1299
* This method computes the distance between this instance of *
1300
* VB_Vector and the input VB_Vector. *
1301
*********************************************************************/
1302
double VB_Vector::euclideanDistance(const VB_Vector& V2) const
1305
/*********************************************************************
1306
* Calling this->euclideanDistance(const gsl_vector *) const. *
1307
*********************************************************************/
1308
return this->euclideanDistance(V2.theVector);
1310
} // double VB_Vector::euclideanDistance(const VB_Vector& V2) const
1312
/*********************************************************************
1313
* This method computes the distance between this instance of *
1314
* VB_Vector and the input VB_Vector. *
1315
*********************************************************************/
1316
double VB_Vector::euclideanDistance(const VB_Vector *V2) const
1319
/*********************************************************************
1320
* Calling this->euclideanDistance(const gsl_vector *) const. *
1321
*********************************************************************/
1322
return this->euclideanDistance(V2->theVector);
1324
} // double VB_Vector::euclideanDistance(const VB_Vector *V2) const
1326
/*********************************************************************
1327
* This method computes the distance between this instance of *
1328
* VB_Vector and the input gsl_vector struct. *
1329
*********************************************************************/
1330
double VB_Vector::euclideanDistance(const gsl_vector& V2) const
1333
/*********************************************************************
1334
* Calling this->euclideanDistance(const gsl_vector *) const. *
1335
*********************************************************************/
1336
return this->euclideanDistance(&V2);
1338
} // double VB_Vector::euclideanDistance(const gsl_vector& V2) const
1340
/*********************************************************************
1341
* This method computes the distance between this instance of *
1342
* VB_Vector and the input gsl_vector struct. *
1343
*********************************************************************/
1344
double VB_Vector::euclideanDistance(const gsl_vector *V2) const
1347
/*********************************************************************
1348
* Checking to see if the 2 vectors have the same lengths or not. *
1349
*********************************************************************/
1352
VB_Vector::checkVectorLengths(this->theVector, V2, __LINE__,
1353
__FILE__, __FUNCTION__);
1355
catch (GenericExcep &e)
1357
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1360
/*********************************************************************
1361
* By default, if the memory allocation fails, *
1362
* then gsl_vector_calloc() will invoke the GSL error handler *
1363
* which calls abort(), creating a core dump. To forgo this behavior, *
1364
* the GSL error handler is turned off and the current error handler *
1365
* is stored in VB_Vector::currentGSLErrorHandler. This is *
1366
* accomplished by the call to this->turnOffGSLErrorHandler(). *
1367
*********************************************************************/
1368
this->turnOffGSLErrorHandler();
1370
/*********************************************************************
1371
* tempVec will hold a copy of this instance of VB_Vector. tempVec is *
1372
* allocated sufficient memory and then this->theVector is copied to *
1374
*********************************************************************/
1375
gsl_vector *tempVec = gsl_vector_calloc(this->theVector->size);
1377
/*********************************************************************
1378
* If tempVec is null, then we were unsuccessful in allocating memory *
1380
*********************************************************************/
1383
VB_Vector::vectorNull(tempVec);
1385
catch (GenericExcep &e)
1387
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1390
/*********************************************************************
1391
* Now copying the values from this->theVector to tempVec. The *
1392
* try/catch blocks are used to process the exception, if one is *
1394
*********************************************************************/
1397
this->GSLVectorMemcpy(tempVec, this->theVector);
1399
catch (GenericExcep &e)
1401
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1404
/*********************************************************************
1405
* gsl_vector_sub() is called to compute the vector difference and its*
1406
* return value is passed to VB_Vector::checkGSLStatus(). If the *
1407
* return value is non-zero, then an error occurred with the GSL *
1408
* function. VB_Vector::checkGSLStatus() will then process the error *
1409
* by writing out an appropriate error message and then causing this *
1410
* program to exit. *
1411
*********************************************************************/
1412
VB_Vector::checkGSLStatus(gsl_vector_sub(tempVec, V2),
1413
__LINE__, __FILE__, __FUNCTION__);
1415
/*********************************************************************
1416
* Now the Euclidean norm of tempVec is stored in distance, which is *
1417
* equal to the distance between this instance of VB_Vector and the *
1418
* input VB_Vector. *
1419
*********************************************************************/
1420
double distance = gsl_blas_dnrm2(tempVec);
1422
/*********************************************************************
1423
* Now freeing the memory previously allocated to tempVec> *
1424
*********************************************************************/
1425
gsl_vector_free(tempVec);
1427
/*********************************************************************
1428
* We now restore the standard GSL error handler by calling *
1429
* this->restoreGSLErrorHandler(). *
1430
*********************************************************************/
1431
this->restoreGSLErrorHandler();
1433
/*********************************************************************
1434
* Returning the Euclidean distance. *
1435
*********************************************************************/
1438
} // double VB_Vector::euclideanDistance(const gsl_vector *V2) const
1440
/*********************************************************************
1441
* This overloaded operator returns the vector sum of this instance *
1442
* of VB_Vector and the input gsl_vector. *
1443
*********************************************************************/
1444
VB_Vector VB_Vector::operator+(const gsl_vector *V2) const
1447
/*********************************************************************
1448
* If the vector lengths are not equal, then a GenericExcep is thrown.*
1449
* The try/catch blocks are used to process the exception, which will *
1450
* have an appropriate error message. *
1451
*********************************************************************/
1454
VB_Vector::checkVectorLengths(this->theVector, V2, __LINE__, __FILE__, __FUNCTION__);
1456
catch (GenericExcep &e)
1458
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1461
/*********************************************************************
1462
* vectorSum is instantiated to hold the vector sum. *
1463
*********************************************************************/
1464
VB_Vector vectorSum = VB_Vector(this->theVector->size);
1466
/*********************************************************************
1467
* Now copying the values from this->theVector to vectorSum.theVector.*
1468
* The try/catch blocks are used to process the exception, if one is *
1470
*********************************************************************/
1473
this->GSLVectorMemcpy(vectorSum.theVector, this->theVector);
1475
catch (GenericExcep &e)
1477
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1480
/*********************************************************************
1481
* gsl_vector_add() is called to compute the vector sum and its *
1482
* return value is passed to VB_Vector::checkGSLStatus(). If the *
1483
* return value is non-zero, then an error occurred with the GSL *
1484
* function. VB_Vector::checkGSLStatus() will then process the error *
1485
* by writing out an appropriate error message and then causing this *
1486
* program to exit. *
1487
*********************************************************************/
1488
VB_Vector::checkGSLStatus(gsl_vector_add(vectorSum.theVector, V2),
1489
__LINE__, __FILE__, __FUNCTION__);
1491
/*********************************************************************
1492
* Now returning the vector sum. *
1493
*********************************************************************/
1496
} // VB_Vector VB_Vector::operator+(const gsl_vector *V2) const
1498
/*********************************************************************
1499
* This overloaded operator returns the vector sum of this instance *
1500
* of VB_Vector and the input VB_Vector. *
1501
*********************************************************************/
1502
VB_Vector VB_Vector::operator+(const VB_Vector& V2) const
1505
/*********************************************************************
1506
* Returning ((*this) + V2.theVector). *
1507
*********************************************************************/
1508
return ((*this) + V2.theVector);
1510
} // VB_Vector VB_Vector::operator+(const VB_Vector& V2) const
1512
/*********************************************************************
1513
* This overloaded operator returns the vector difference of this *
1514
* instance of VB_Vector and the input gsl_vector. *
1515
*********************************************************************/
1516
VB_Vector VB_Vector::operator-(const gsl_vector *V2) const
1519
/*********************************************************************
1520
* If the vector lengths are not equal, then a GenericExcep is thrown.*
1521
* The try/catch blocks are used to process the exception, which will *
1522
* have an appropriate error message. *
1523
*********************************************************************/
1526
VB_Vector::checkVectorLengths(this->theVector, V2, __LINE__, __FILE__, __FUNCTION__);
1528
catch (GenericExcep &e)
1530
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1533
/*********************************************************************
1534
* vectorDiff is instantiated to hold the vector difference. *
1535
*********************************************************************/
1536
VB_Vector vectorDiff = VB_Vector(this->theVector->size);
1538
/*********************************************************************
1539
* Now copying the values from this->theVector to *
1540
* vectorDiff.theVector. The try/catch blocks are used to process the *
1541
* exception, if one is thrown. *
1542
*********************************************************************/
1545
this->GSLVectorMemcpy(vectorDiff.theVector, this->theVector);
1547
catch (GenericExcep &e)
1549
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1552
/*********************************************************************
1553
* gsl_vector_sub() is called to compute the vector difference and its*
1554
* return value is passed to VB_Vector::checkGSLStatus(). If the *
1555
* return value is non-zero, then an error occurred with the GSL *
1556
* function. VB_Vector::checkGSLStatus() will then process the error *
1557
* by writing out an appropriate error message and then causing this *
1558
* program to exit. *
1559
*********************************************************************/
1560
VB_Vector::checkGSLStatus(gsl_vector_sub(vectorDiff.theVector, V2),
1561
__LINE__, __FILE__, __FUNCTION__);
1563
/*********************************************************************
1564
* Now returning the vector difference. *
1565
*********************************************************************/
1568
} // VB_Vector VB_Vector::operator-(const gsl_vector *V2) const
1570
/*********************************************************************
1571
* This overloaded operator returns the vector difference of this *
1572
* instance of VB_Vector and the input VB_Vector. *
1573
*********************************************************************/
1574
VB_Vector VB_Vector::operator-(const VB_Vector& V2) const
1577
/*********************************************************************
1578
* Returning ((*this) - V2.theVector). *
1579
*********************************************************************/
1580
return ((*this) - V2.theVector);
1582
} // VB_Vector VB_Vector::operator-(const VB_Vector& V2) const
1584
/*********************************************************************
1585
* This overloaded operator returns the vector difference of this *
1586
* instance of VB_Vector and the input VB_Vector. *
1587
*********************************************************************/
1588
VB_Vector VB_Vector::operator-(const VB_Vector *V2) const
1591
/*********************************************************************
1592
* Returning the difference of (*this) and V2->theVector. *
1593
*********************************************************************/
1594
return ((*this) - V2->theVector);
1596
} // VB_Vector VB_Vector::operator-(const VB_Vector *V2) const
1598
/*********************************************************************
1599
* This overloaded operator returns the vector difference of this *
1600
* instance of VB_Vector and the input gsl_vector struct. *
1601
*********************************************************************/
1602
VB_Vector VB_Vector::operator-(const gsl_vector& V2) const
1605
/*********************************************************************
1606
* Returning the difference of (*this) and (&V2). *
1607
*********************************************************************/
1608
return ((*this) - (&V2));
1610
} // VB_Vector VB_Vector::operator-(const gsl_vector& V2) const
1612
/*********************************************************************
1613
* This is the overloaded [] operator. NOTE: A reference is returned, *
1614
* allowing assignment. *
1615
*********************************************************************/
1616
double& VB_Vector::operator[](const size_t index) const
1619
/*********************************************************************
1620
* Returning the specified reference. *
1621
*********************************************************************/
1622
return this->theVector->data[index];
1624
} // double& VB_Vector::operator[](const size_t index) const
1626
/*********************************************************************
1627
* Overloaded "()" operator. Behaves just like the overloaded "[]" *
1628
* operator for this class except index is range checked. *
1629
*********************************************************************/
1630
double& VB_Vector::operator()(const size_t index) const
1633
/*********************************************************************
1634
* A try/catch block is used to determine if index is out of range or *
1636
*********************************************************************/
1640
/*********************************************************************
1641
* We now check to make sure that index is within *
1642
* [0, this->theVector->size - 1]. *
1643
*********************************************************************/
1644
this->checkVectorRange(index, __LINE__, __FILE__, __FUNCTION__);
1647
catch (GenericExcep &e)
1649
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1652
/*********************************************************************
1653
* Returning the specified reference. *
1654
*********************************************************************/
1655
return this->theVector->data[index];
1657
} // double& VB_Vector::operator()(const size_t index) const
1659
/*********************************************************************
1660
* This overloaded operator checks for equality between this instance *
1661
* of VB_Vector and the input VB_Vector. *
1662
*********************************************************************/
1663
bool VB_Vector::operator==(const VB_Vector *V2) const
1666
/*********************************************************************
1667
* Returning the value of the call to operator==(gsl_vector *). *
1668
*********************************************************************/
1669
return ((*this) == V2->theVector);
1671
} // bool VB_Vector::operator==(const VB_Vector *V2) const
1673
/*********************************************************************
1674
* This overloaded operator checks for equality between this instance *
1675
* of VB_Vector and the input VB_Vector. *
1676
*********************************************************************/
1677
bool VB_Vector::operator==(const VB_Vector& V2) const
1680
/*********************************************************************
1681
* Returning the value of the call to operator==(gsl_vector *). *
1682
*********************************************************************/
1683
return ((*this) == V2.theVector);
1685
} // bool VB_Vector::operator==(const VB_Vector& V2) const
1687
/*********************************************************************
1688
* This overloaded operator checks for equality between this instance *
1689
* of VB_Vector and the input gsl_vector struct. *
1690
*********************************************************************/
1691
bool VB_Vector::operator==(const gsl_vector *V2) const
1694
/*********************************************************************
1695
* If both this->theVector and V2 are NULL, then true is returned. *
1696
*********************************************************************/
1697
if (this->theVector==NULL && V2==NULL)
1700
/*********************************************************************
1701
* If one of {this->theVector, V2} is NULL and the other is not, then *
1702
* false is returned. *
1703
*********************************************************************/
1704
if ( (this->theVector && V2==NULL) || (this->theVector==NULL && V2))
1707
/*********************************************************************
1708
* If this->theVector->size and V2->size are not equal, then false is *
1710
*********************************************************************/
1711
if (this->theVector->size != V2->size)
1716
/*********************************************************************
1717
* memcmp() returns 0 if the 2 memory areas have the same content. *
1718
*********************************************************************/
1719
return (memcmp(this->theVector, V2, this->theVector->size * sizeof(double)) == 0);
1721
} // bool VB_Vector::operator==(const gsl_vector *V2) const
1723
/*********************************************************************
1724
* This overloaded operator checks for equality between this instance *
1725
* of VB_Vector and the input gsl_vector struct. *
1726
*********************************************************************/
1727
bool VB_Vector::operator==(const gsl_vector& V2) const
1730
/*********************************************************************
1731
* Returning the value of the call to operator==(gsl_vector *). *
1732
*********************************************************************/
1733
return ((*this) == (&V2));
1735
} // bool VB_Vector::operator==(const gsl_vector& V2) const
1737
/*********************************************************************
1738
* This overloaded operator checks for inequality between this *
1739
* instance of VB_Vector and the input VB_Vector. *
1740
*********************************************************************/
1741
bool VB_Vector::operator!=(const VB_Vector *V2) const
1744
/*********************************************************************
1745
* Returning the negation of the equality check. *
1746
*********************************************************************/
1747
return !((*this) == V2);
1749
} // bool VB_Vector::operator!=(const VB_Vector *V2) const
1751
/*********************************************************************
1752
* This overloaded operator checks for inequality between this *
1753
* instance of VB_Vector and the input VB_Vector. *
1754
*********************************************************************/
1755
bool VB_Vector::operator!=(const VB_Vector& V2) const
1758
/*********************************************************************
1759
* Returning the negation of the equality check. *
1760
*********************************************************************/
1761
return !((*this) == V2);
1763
} // bool VB_Vector::operator!=(const VB_Vector& V2) const
1765
/*********************************************************************
1766
* This overloaded operator checks for inequality between this *
1767
* instance of VB_Vector and the input gsl_vector struct. *
1768
*********************************************************************/
1769
bool VB_Vector::operator!=(const gsl_vector& V2) const
1772
/*********************************************************************
1773
* Returning the negation of the equality check. *
1774
*********************************************************************/
1775
return !((*this) == V2);
1777
} // bool VB_Vector::operator!=(const gsl_vector& V2) const
1779
/*********************************************************************
1780
* This overloaded operator checks for inequality between this *
1781
* instance of VB_Vector and the input gsl_vector struct. *
1782
*********************************************************************/
1783
bool VB_Vector::operator!=(const gsl_vector *V2) const
1786
/*********************************************************************
1787
* Returning the negation of the equality check. *
1788
*********************************************************************/
1789
return !((*this) == V2);
1791
} // bool VB_Vector::operator!=(const gsl_vector *V2) const
1794
VB_Vector::operator=(const VB_Vector& V2)
1798
if (V2.getLength()==0) {
1802
this->init(this->valid, V2.dataType,V2.fileFormat);
1803
this->init(V2.getLength());
1804
if (!(this->theVector))
1806
this->fileName=V2.fileName;
1807
this->GSLVectorMemcpy(this->theVector, V2.theVector);
1814
gsl_vector_set_zero(this->theVector);
1818
/*********************************************************************
1819
* This static method returns a VB_Vector object that represents a *
1821
*********************************************************************/
1822
VB_Vector VB_Vector::getBasisVector(const size_t length, const size_t index)
1825
/*********************************************************************
1826
* Instantiating a VB_Vector whose length will be length. NOTE: All *
1827
* the elements will be zero. *
1828
*********************************************************************/
1829
VB_Vector basis(length);
1831
/*********************************************************************
1832
* Now setting the appropriate element to 1. *
1833
*********************************************************************/
1834
basis.setElement(index, 1.0);
1836
/*********************************************************************
1837
* Now returning the basis VB_Vector. *
1838
*********************************************************************/
1841
} // VB_Vector VB_Vector::getBasisVector(const size_t length, const size_t index)
1843
/*********************************************************************
1844
* This method scales the elements of this instance of VB_Vector by *
1845
* alpha and returns the scaled vector. *
1846
*********************************************************************/
1847
VB_Vector VB_Vector::vectorScale(const double alpha) const
1850
/*********************************************************************
1851
* By default, if the memory allocation fails, *
1852
* then gsl_vector_calloc() will invoke the GSL error handler *
1853
* which calls abort(), creating a core dump. To forgo this behavior, *
1854
* the GSL error handler is turned off and the current error handler *
1855
* is stored in VB_Vector::currentGSLErrorHandler. This is *
1856
* accomplished by the call to this->turnOffGSLErrorHandler(). *
1857
*********************************************************************/
1858
this->turnOffGSLErrorHandler();
1860
/*********************************************************************
1861
* tempVec will hold a copy of this instance of VB_Vector. tempVec is *
1862
* allocated sufficient memory and then this->theVector is copied to *
1864
*********************************************************************/
1865
gsl_vector *tempVec = gsl_vector_calloc(this->getLength());
1867
/*********************************************************************
1868
* We now restore the standard GSL error handler by calling *
1869
* this->restoreGSLErrorHandler(). *
1870
*********************************************************************/
1871
this->restoreGSLErrorHandler();
1873
/*********************************************************************
1874
* If tempVec is null, then we were unsuccessful in allocating memory *
1876
*********************************************************************/
1879
VB_Vector::vectorNull(tempVec);
1881
catch (GenericExcep &e)
1883
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1886
/*********************************************************************
1887
* Now copying the values from this->theVector to tempVec. The *
1888
* try/catch blocks are used to process the exception, if one is *
1890
*********************************************************************/
1893
this->GSLVectorMemcpy(tempVec, this->theVector);
1895
catch (GenericExcep &e)
1897
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
1900
/*********************************************************************
1901
* gsl_vector_scale() is called to do the scaling and its *
1902
* return value is passed to VB_Vector::checkGSLStatus(). If the *
1903
* return value is non-zero, then an error occurred with the GSL *
1904
* function. VB_Vector::checkGSLStatus() will then process the error *
1905
* by writing out an appropriate error message and then causing this *
1906
* program to exit. *
1907
*********************************************************************/
1908
VB_Vector::checkGSLStatus(gsl_vector_scale(tempVec, alpha),
1909
__LINE__, __FILE__, __FUNCTION__);
1911
/*********************************************************************
1912
* Now returning the scaled vector, tempVec, as a VB_Vector object. *
1913
*********************************************************************/
1914
return VB_Vector(tempVec);
1916
} // VB_Vector VB_Vector::vectorScale(const double alpha) const
1918
/*********************************************************************
1919
* This method adds the constant alpha to all elements of the *
1921
*********************************************************************/
1922
void VB_Vector::addConstant(const double alpha)
1925
/*********************************************************************
1926
* gsl_vector_add_constant() is called to add the constant and its *
1927
* return value is passed to VB_Vector::checkGSLStatus(). If the *
1928
* return value is non-zero, then an error occurred with the GSL *
1929
* function. VB_Vector::checkGSLStatus() will then process the error *
1930
* by writing out an appropriate error message and then causing this *
1931
* program to exit. *
1932
*********************************************************************/
1933
VB_Vector::checkGSLStatus(gsl_vector_add_constant(this->theVector, alpha),
1934
__LINE__, __FILE__, __FUNCTION__);
1936
} // void VB_Vector::addConstant(const double alpha)
1938
/*********************************************************************
1939
* This overloaded operator returns the vector sum of this instance *
1940
* of VB_Vector and the input VB_Vector. *
1941
*********************************************************************/
1942
VB_Vector VB_Vector::operator+(const VB_Vector *V2) const
1945
/*********************************************************************
1946
* Returning the sum of (*this) and V2->theVector. *
1947
*********************************************************************/
1948
return ((*this) + V2->theVector);
1950
} // VB_Vector VB_Vector::operator+(const VB_Vector *V2) const
1952
/*********************************************************************
1953
* This overloaded operator returns the vector sum of this instance *
1954
* of VB_Vector and the input gsl_vector struct. *
1955
*********************************************************************/
1956
VB_Vector VB_Vector::operator+(const gsl_vector& V2) const
1959
/*********************************************************************
1960
* Returning the sum of (*this) and (&V2). *
1961
*********************************************************************/
1962
return ((*this) + (&V2));
1964
} // VB_Vector VB_Vector::operator+(const gsl_vector& V2) const
1966
/*********************************************************************
1967
* This overloaded "+" operator is a friend function. This overloaded *
1968
* operator is implemented to preserve the commutative property for *
1969
* addition between VB_Vector and gsl_vector. *
1970
*********************************************************************/
1971
VB_Vector operator+(const gsl_vector *V1, const VB_Vector& V2)
1974
/*********************************************************************
1975
* Returning the sum of V2 and V1. *
1976
*********************************************************************/
1979
} // VB_Vector operator+(const gsl_vector *V1, const VB_Vector& V2)
1981
/*********************************************************************
1982
* This overloaded "+" operator is a friend function. This overloaded *
1983
* operator is implemented to preserve the commutative property for *
1984
* addition between VB_Vector and gsl_vector. *
1985
*********************************************************************/
1986
VB_Vector operator+(const gsl_vector& V1, const VB_Vector *V2)
1989
/*********************************************************************
1990
* Returning the sum of V2 and V1. *
1991
*********************************************************************/
1992
return ((*V2) + (&V1));
1994
} // VB_Vector operator+(const gsl_vector& V1, const VB_Vector *V2)
1996
/*********************************************************************
1997
* This overloaded "+" operator is a friend function. This overloaded *
1998
* operator is implemented to preserve the commutative property for *
1999
* addition between VB_Vector and gsl_vector. *
2000
*********************************************************************/
2001
VB_Vector operator+(const gsl_vector& V1, const VB_Vector& V2)
2004
/*********************************************************************
2005
* Returning the sum of V2 and V1. *
2006
*********************************************************************/
2007
return (V2 + (&V1));
2009
} // VB_Vector operator+(const gsl_vector& V1, const VB_Vector& V2)
2011
/*********************************************************************
2012
* This overloaded operator is implemented as a friend function so *
2013
* that commutativity can be preserved for "==". *
2014
*********************************************************************/
2015
bool operator==(const gsl_vector *V1, const VB_Vector& V2)
2018
/*********************************************************************
2019
* If V2.theVector->size and V1->size are not equal, then false is *
2021
*********************************************************************/
2022
if (V2.getLength() != V1->size)
2027
/*********************************************************************
2028
* memcmp() returns 0 if the 2 memory areas are equal. *
2029
*********************************************************************/
2030
return (memcmp(V2.theVector, V1, V2.getLength() * sizeof(double)) == 0);
2032
} // bool operator==(const gsl_vector *V1, const VB_Vector& V2)
2034
/*********************************************************************
2035
* This overloaded operator is implemented as a friend function so *
2036
* that commutativity can be preserved for "==". *
2037
*********************************************************************/
2038
bool operator==(const gsl_vector& V1, const VB_Vector& V2)
2041
/*********************************************************************
2042
* memcmp() returns 0 if the 2 memory areas are equal. *
2043
*********************************************************************/
2044
return (memcmp(V2.theVector, &V1, V2.getLength() * sizeof(double)) == 0);
2046
} // bool operator==(const gsl_vector& V1, const VB_Vector& V2)
2048
/*********************************************************************
2049
* This overloaded "!=" is implemented as a friend function to *
2050
* preserve commutativity. *
2051
*********************************************************************/
2052
bool operator!=(const gsl_vector *V1, const VB_Vector& V2)
2055
/*********************************************************************
2056
* Returning the negation of the equality check. *
2057
*********************************************************************/
2060
} // bool operator!=(const gsl_vector *V1, const VB_Vector& V2)
2062
/*********************************************************************
2063
* This overloaded "!=" is implemented as a friend function to *
2064
* preserve commutativity. *
2065
*********************************************************************/
2066
bool operator!=(const gsl_vector& V1, const VB_Vector& V2)
2069
/*********************************************************************
2070
* Returning the negation of the equality check. *
2071
*********************************************************************/
2074
} // bool operator!=(const gsl_vector& V1, const VB_Vector& V2)
2076
/*********************************************************************
2077
* This overloaded "<<" operator is implemented as a friend function. *
2078
*********************************************************************/
2079
ostream& operator<<(ostream& outStream, const VB_Vector& V)
2082
/*********************************************************************
2083
* Now calling operator<<(ostream&, const VB_Vector *), whose return *
2084
* value, in turn, is returned by this function. *
2085
*********************************************************************/
2086
return (outStream << (&V));
2088
} // ostream& operator<<(ostream& outStream, const VB_Vector& V)
2090
/*********************************************************************
2091
* This overloaded "<<" operator is implemented as a friend function. *
2092
*********************************************************************/
2093
ostream& operator<<(ostream& outStream, const VB_Vector *V)
2096
/*********************************************************************
2097
* Printing out the file name, valid flag, data type, and file type *
2099
*********************************************************************/
2100
outStream << "Vector File Name = [" << V->fileName << "]" << endl;
2101
outStream << "Vector Valid = [" << V->valid << "]" << endl;
2102
outStream << "Vector Data Type = [" << DataTypeName(V->dataType) << "]" << endl;
2103
// DYK replaced the following
2104
// outStream << "Vector File Type = [" << (V->fileFormat ? V->fileFormat->getName() : "NONE") << "]" << endl;
2105
outStream << "Vector File Type = [" << V->fileFormat.getName() << "]" << endl;
2107
/*********************************************************************
2108
* If the input VB_Vector does not have a null theVector data member, *
2109
* then the vector elements are printed out. *
2110
*********************************************************************/
2114
/*********************************************************************
2115
* Writing out the fields from the data member theVector, a *
2116
* gsl_vector struct. *
2117
*********************************************************************/
2118
outStream << "gsl_vector stride = [" << V->theVector->stride << "]" << endl;
2119
outStream << "gsl_vector owner = [" << V->theVector->owner << "]" << endl;
2120
outStream << "Vector Length = [" << V->theVector->size << "]" << endl;
2122
/*********************************************************************
2123
* The following for loop is used to write out the vector elements. *
2124
*********************************************************************/
2125
for (size_t i = 0; i < V->theVector->size; i++)
2127
outStream << "element[" << i << "] = [" << V->theVector->data[i] << "]" << endl;
2132
/*********************************************************************
2133
* If program flow ends up here, then V->getTheVector() returned a *
2134
* null gsl_vector. *
2135
*********************************************************************/
2138
outStream << "NULL gsl_vector." << endl;
2141
/*********************************************************************
2142
* Now returning outStream. *
2143
*********************************************************************/
2146
} // ostream& operator<<(ostream& outStream, const VB_Vector *V)
2148
/*********************************************************************
2149
* This is a static method to compute the Euclidean distance between *
2150
* the two input gsl_vector structs. *
2151
*********************************************************************/
2152
double VB_Vector::euclideanDistance(const gsl_vector *V1, const gsl_vector *V2)
2155
/*********************************************************************
2156
* tempVec is instantiated from V1 as a VB_Vector object. *
2157
*********************************************************************/
2158
VB_Vector tempVec(V1);
2160
/*********************************************************************
2161
* Now calling tempVec.euclideanDistance() to return the Euclidean *
2162
* distance between V1 and V2. *
2163
*********************************************************************/
2164
return tempVec.euclideanDistance(V2);
2166
} // double VB_Vector::euclideanDistance(const gsl_vector *V1, const gsl_vector *V2)
2168
/*********************************************************************
2169
* This is a static method to compute the Euclidean distance between *
2170
* the two input gsl_vector structs. *
2171
*********************************************************************/
2172
double VB_Vector::euclideanDistance(const gsl_vector& V1, const gsl_vector& V2)
2175
/*********************************************************************
2176
* tempVec is instantiated from V1 as a VB_Vector object. *
2177
*********************************************************************/
2178
VB_Vector tempVec(V1);
2180
/*********************************************************************
2181
* Now calling tempVec.euclideanDistance() to return the Euclidean *
2182
* distance between V1 and V2. *
2183
*********************************************************************/
2184
return tempVec.euclideanDistance(V2);
2186
} // double VB_Vector::euclideanDistance(const gsl_vector& V1, const gsl_vector& V2)
2188
/*********************************************************************
2189
* This method adds V to this instance of VB_Vector in place (this *
2190
* instance of VB_Vector gets overwritten by the vector sum). *
2191
*********************************************************************/
2192
void VB_Vector::addInPlace(const VB_Vector& V)
2195
/*********************************************************************
2196
* Calling this->addInPlace(gsl_vector *) to carry out the addition. *
2197
*********************************************************************/
2198
this->addInPlace(V.theVector);
2200
} // void VB_Vector::addInPlace(const VB_Vector& V)
2202
/*********************************************************************
2203
* This method adds V to this instance of VB_Vector in place (this *
2204
* instance of VB_Vector gets overwritten by the vector sum). *
2205
*********************************************************************/
2206
void VB_Vector::addInPlace(const VB_Vector *V)
2209
/*********************************************************************
2210
* Calling this->addInPlace(gsl_vector *) to carry out the addition. *
2211
*********************************************************************/
2212
this->addInPlace(V->theVector);
2214
} // void VB_Vector::addInPlace(const VB_Vector *V)
2216
/*********************************************************************
2217
* This method adds V to this instance of VB_Vector in place (this *
2218
* instance of VB_Vector gets overwritten by the vector sum). *
2219
*********************************************************************/
2220
void VB_Vector::addInPlace(const gsl_vector& V)
2223
/*********************************************************************
2224
* Calling this->addInPlace(gsl_vector *) to carry out the addition. *
2225
*********************************************************************/
2226
this->addInPlace(&V);
2228
} // void VB_Vector::addInPlace(const gsl_vector& V)
2230
/*********************************************************************
2231
* This method adds V to this instance of VB_Vector in place (this *
2232
* instance of VB_Vector gets overwritten by the vector sum). *
2233
*********************************************************************/
2234
void VB_Vector::addInPlace(const gsl_vector *V)
2237
/*********************************************************************
2238
* gsl_vector_add() is called to compute the vector sum and its *
2239
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2240
* return value is non-zero, then a error occurred with the GSL *
2241
* function. VB_Vector::checkGSLStatus() will then process the error *
2242
* by writing out an appropriate error message and then causing this *
2243
* program to exit. *
2244
*********************************************************************/
2245
VB_Vector::checkGSLStatus(gsl_vector_add(this->theVector, V),
2246
__LINE__, __FILE__, __FUNCTION__);
2248
} // void VB_Vector::addInPlace(const gsl_vector *V)
2250
/*********************************************************************
2251
* This method subtracts V from this instance of VB_Vector in place *
2252
* (this instance of VB_Vector gets overwritten by the vector *
2254
*********************************************************************/
2255
void VB_Vector::subtractInPlace(const VB_Vector& V)
2258
/*********************************************************************
2259
* Calling this->subtractInPlace(gsl_vector *) to carry out the *
2261
*********************************************************************/
2262
this->subtractInPlace(V.theVector);
2264
} // void VB_Vector::subtractInPlace(const VB_Vector& V)
2266
/*********************************************************************
2267
* This method subtracts V from this instance of VB_Vector in place *
2268
* (this instance of VB_Vector gets overwritten by the vector *
2270
*********************************************************************/
2271
void VB_Vector::subtractInPlace(const VB_Vector *V)
2274
/*********************************************************************
2275
* Calling this->subtractInPlace(gsl_vector *) to carry out the *
2277
*********************************************************************/
2278
this->subtractInPlace(V->theVector);
2280
} // void VB_Vector::subtractInPlace(const VB_Vector *V)
2282
/*********************************************************************
2283
* This method subtracts V from this instance of VB_Vector in place *
2284
* (this instance of VB_Vector gets overwritten by the vector *
2286
*********************************************************************/
2287
void VB_Vector::subtractInPlace(const gsl_vector& V)
2290
/*********************************************************************
2291
* Calling this->subtractInPlace(gsl_vector *) to carry out the *
2293
*********************************************************************/
2294
this->subtractInPlace(&V);
2296
} // void VB_Vector::subtractInPlace(const gsl_vector& V)
2298
/*********************************************************************
2299
* This method subtracts V from this instance of VB_Vector in place *
2300
* (this instance of VB_Vector gets overwritten by the vector *
2302
*********************************************************************/
2303
void VB_Vector::subtractInPlace(const gsl_vector *V)
2306
/*********************************************************************
2307
* gsl_vector_sub() is called to compute the difference and its *
2308
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2309
* return value is non-zero, then a error occurred with the GSL *
2310
* function. VB_Vector::checkGSLStatus() will then process the error *
2311
* by writing out an appropriate error message and then causing this *
2312
* program to exit. *
2313
*********************************************************************/
2314
VB_Vector::checkGSLStatus(gsl_vector_sub(this->theVector, V),
2315
__LINE__, __FILE__, __FUNCTION__);
2317
} // void VB_Vector::subtractInPlace(const gsl_vector *V)
2319
/*********************************************************************
2320
* This method scales the elements of this instance of VB_Vector by *
2322
*********************************************************************/
2323
void VB_Vector::scaleInPlace(const double alpha)
2326
/*********************************************************************
2327
* gsl_vector_scale() is called to do the scaling and its *
2328
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2329
* return value is non-zero, then a error occurred with the GSL *
2330
* function. VB_Vector::checkGSLStatus() will then process the error *
2331
* by writing out an appropriate error message and then causing this *
2332
* program to exit. *
2333
*********************************************************************/
2334
VB_Vector::checkGSLStatus(gsl_vector_scale(this->theVector, alpha),
2335
__LINE__, __FILE__, __FUNCTION__);
2337
} // void VB_Vector::scaleInPlace(const double alpha)
2339
/*********************************************************************
2340
* This overloaded "*" operator returns the Euclidean inner product of*
2341
* this instance of VB_Vector with the input vector. *
2342
*********************************************************************/
2343
double VB_Vector::operator*(const VB_Vector *V2) const
2346
/*********************************************************************
2347
* Now returning the Euclidean inner product. *
2348
*********************************************************************/
2349
return this->euclideanProduct(V2->theVector);
2351
} // double VB_Vector::operator*(const VB_Vector *V2) const
2353
/*********************************************************************
2354
* This overloaded "*" operator returns the Euclidean inner product of*
2355
* this instance of VB_Vector with the input vector. *
2356
*********************************************************************/
2357
double VB_Vector::operator*(const VB_Vector& V2) const
2360
/*********************************************************************
2361
* Now returning the Euclidean inner product. *
2362
*********************************************************************/
2363
return this->euclideanProduct(V2.theVector);
2365
} // double VB_Vector::operator*(const VB_Vector& V2) const
2367
/*********************************************************************
2368
* This overloaded "*" operator returns the Euclidean inner product of*
2369
* this instance of VB_Vector with the input vector. *
2370
*********************************************************************/
2371
double VB_Vector::operator*(const gsl_vector& V2) const
2374
/*********************************************************************
2375
* Now returning the Euclidean inner product. *
2376
*********************************************************************/
2377
return this->euclideanProduct(&V2);
2379
} // double VB_Vector::operator*(const gsl_vector& V2) const
2381
/*********************************************************************
2382
* This overloaded "*" operator returns the Euclidean inner product of*
2383
* this instance of VB_Vector with the input vector. *
2384
*********************************************************************/
2385
double VB_Vector::operator*(const gsl_vector *V2) const
2388
/*********************************************************************
2389
* Now returning the Euclidean inner product. *
2390
*********************************************************************/
2391
return this->euclideanProduct(V2);
2393
} // double VB_Vector::operator*(const gsl_vector& V2) const
2395
/*********************************************************************
2396
* Overloaded "*" operator (a friend function) that returns the *
2397
* Euclidean inner product of the 2 input vectors. *
2398
*********************************************************************/
2399
double operator*(const gsl_vector *V1, const VB_Vector& V2)
2402
/*********************************************************************
2403
* Now calling V2.euclideanProduct(V1) to compute the Euclidean inner *
2405
*********************************************************************/
2406
return V2.euclideanProduct(V1);
2408
} // double operator*(const gsl_vector *V1, const VB_Vector& V2)
2410
/*********************************************************************
2411
* Overloaded "*" operator (a friend function) that returns the *
2412
* Euclidean inner product of the 2 input vectors. *
2413
*********************************************************************/
2414
double operator*(const gsl_vector& V1, const VB_Vector& V2)
2417
/*********************************************************************
2418
* Now calling V2.euclideanProduct(V1) to compute the Euclidean inner *
2420
*********************************************************************/
2421
return V2.euclideanProduct(&V1);
2423
} // double operator*(const gsl_vector& V1, const VB_Vector& V2)
2425
/*********************************************************************
2426
* Overloaded "*" operator (a friend function) that returns the *
2427
* Euclidean inner product of the 2 input vectors. *
2428
*********************************************************************/
2429
double operator*(const gsl_vector& V1, const VB_Vector *V2)
2432
/*********************************************************************
2433
* Now calling V2.euclideanProduct(V1) to compute the Euclidean inner *
2435
*********************************************************************/
2436
return V2->euclideanProduct(&V1);
2438
} // double operator*(const gsl_vector& V1, const VB_Vector *V2)
2440
/*********************************************************************
2441
* This overloaded operator adds the input scalar to all elements of *
2442
* this instance of VB_Vector, in place. *
2443
*********************************************************************/
2444
VB_Vector& VB_Vector::operator+=(const double alpha)
2447
/*********************************************************************
2448
* gsl_vector_add_constant() is called to add the constant and its *
2449
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2450
* return value is non-zero, then a error occurred with the GSL *
2451
* function. VB_Vector::checkGSLStatus() will then process the error *
2452
* by writing out an appropriate error message and then causing this *
2453
* program to exit. *
2454
*********************************************************************/
2455
VB_Vector::checkGSLStatus(gsl_vector_add_constant(this->theVector, alpha),
2456
__LINE__, __FILE__, __FUNCTION__);
2458
/*********************************************************************
2459
* Now returning a reference to this instance of VB_Vector. *
2460
*********************************************************************/
2463
} // VB_Vector& VB_Vector::operator+=(const double alpha)
2465
/*********************************************************************
2466
* This overloaded operator subtracts the input scalar to all *
2467
* elements of this instance of VB_Vector, in place. *
2468
*********************************************************************/
2469
VB_Vector& VB_Vector::operator-=(const double alpha)
2472
/*********************************************************************
2473
* gsl_vector_add_constant() is called to subtract the constant and *
2474
* its return value is passed to VB_Vector::checkGSLStatus(). If the *
2475
* return value is non-zero, then a error occurred with the GSL *
2476
* function. VB_Vector::checkGSLStatus() will then process the error *
2477
* by writing out an appropriate error message and then causing this *
2478
* program to exit. *
2479
*********************************************************************/
2480
VB_Vector::checkGSLStatus(gsl_vector_add_constant(this->theVector, -1.0 * alpha),
2481
__LINE__, __FILE__, __FUNCTION__);
2483
/*********************************************************************
2484
* Now returning a reference to this instance of VB_Vector. *
2485
*********************************************************************/
2488
} // VB_Vector& VB_Vector::operator-=(const double alpha)
2490
/*********************************************************************
2491
* This overloaded operator multiplies each element of this instance *
2492
* of VB_Vector by the input scalar, in place. *
2493
*********************************************************************/
2494
VB_Vector& VB_Vector::operator*=(const double alpha)
2497
/*********************************************************************
2498
* gsl_vector_scale() is called to do the scaling and its *
2499
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2500
* return value is non-zero, then a error occurred with the GSL *
2501
* function. VB_Vector::checkGSLStatus() will then process the error *
2502
* by writing out an appropriate error message and then causing this *
2503
* program to exit. *
2504
*********************************************************************/
2505
VB_Vector::checkGSLStatus(gsl_vector_scale(this->theVector, alpha),
2506
__LINE__, __FILE__, __FUNCTION__);
2508
/*********************************************************************
2509
* Now returning a reference to this instance of VB_Vector. *
2510
*********************************************************************/
2513
} // VB_Vector& VB_Vector::operator*=(const double alpha)
2515
/*********************************************************************
2516
* This overloaded operator multiplies each element of this instance *
2517
* of VB_Vector by the reciprocal of the input scalar, in place. *
2518
*********************************************************************/
2519
VB_Vector& VB_Vector::operator/=(const double alpha)
2522
/*********************************************************************
2523
* If alpha is 0.0, then an exception is thrown. *
2524
*********************************************************************/
2528
/*********************************************************************
2529
* Calling VB_Vector::createException() to throw and catch a *
2530
* GenericExcep so that the appropriate error messaqge can be printed.*
2531
*********************************************************************/
2532
VB_Vector::createException(string("Can not divide by a zero scalar value."),
2533
__LINE__, __FILE__, __FUNCTION__);
2537
/*********************************************************************
2538
* Calling gsl_vector_scale() to carry out the scaling by the *
2539
* reciprocal. status will hold the return value of *
2540
* gsl_vector_scale(). *
2541
*********************************************************************/
2542
double reciprocal = 1.0 / alpha;
2544
/*********************************************************************
2545
* gsl_vector_scale() is called to do the needed scaling and its *
2546
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2547
* return value is non-zero, then a error occurred with the GSL *
2548
* function. VB_Vector::checkGSLStatus() will then process the error *
2549
* by writing out an appropriate error message and then causing this *
2550
* program to exit. *
2551
*********************************************************************/
2552
VB_Vector::checkGSLStatus(gsl_vector_scale(this->theVector, reciprocal),
2553
__LINE__, __FILE__, __FUNCTION__);
2555
/*********************************************************************
2556
* VB_Vector::checkFiniteness() is called to ensure that all elements *
2557
* of this->theVector are finite, i.e., no Inf's nor Nan's. *
2558
*********************************************************************/
2559
VB_Vector::checkFiniteness(this->theVector, __LINE__, __FILE__, __FUNCTION__);
2562
/*********************************************************************
2563
* Now returning a reference to this instance of VB_Vector. *
2564
*********************************************************************/
2567
} // VB_Vector& VB_Vector::operator/=(const double alpha)
2569
/*********************************************************************
2570
* This overloaded operator adds the input vector to this instance of *
2571
* VB_Vector, in place. *
2572
*********************************************************************/
2573
VB_Vector& VB_Vector::operator+=(const VB_Vector& V)
2576
/*********************************************************************
2577
* gsl_vector_add() is called to compute the vector sum and its *
2578
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2579
* return value is non-zero, then a error occurred with the GSL *
2580
* function. VB_Vector::checkGSLStatus() will then process the error *
2581
* by writing out an appropriate error message and then causing this *
2582
* program to exit. *
2583
*********************************************************************/
2584
VB_Vector::checkGSLStatus(gsl_vector_add(this->theVector, V.theVector),
2585
__LINE__, __FILE__, __FUNCTION__);
2587
/*********************************************************************
2588
* Now returning a reference to this instance of VB_Vector. *
2589
*********************************************************************/
2592
} // VB_Vector& VB_Vector::operator+=(const VB_Vector& V)
2594
/*********************************************************************
2595
* This overloaded operator subtracts the input vector from this *
2596
* instance of VB_Vector, in place. *
2597
*********************************************************************/
2598
VB_Vector& VB_Vector::operator-=(const VB_Vector& V)
2601
/*********************************************************************
2602
* gsl_vector_sub() is called to compute the vector difference and its*
2603
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2604
* return value is non-zero, then a error occurred with the GSL *
2605
* function. VB_Vector::checkGSLStatus() will then process the error *
2606
* by writing out an appropriate error message and then causing this *
2607
* program to exit. *
2608
*********************************************************************/
2609
VB_Vector::checkGSLStatus(gsl_vector_sub(this->theVector, V.theVector),
2610
__LINE__, __FILE__, __FUNCTION__);
2612
/*********************************************************************
2613
* Now returning a reference to this instance of VB_Vector. *
2614
*********************************************************************/
2617
} // VB_Vector& VB_Vector::operator-=(const VB_Vector& V)
2619
/*********************************************************************
2620
* This overloaded operator multiplies each element of this instance *
2621
* of VB_Vector by the corresponding element of the input vector, in *
2623
*********************************************************************/
2624
VB_Vector& VB_Vector::operator*=(const VB_Vector& V)
2627
/*********************************************************************
2628
* gsl_vector_mul() is called to compute the element by element *
2629
* product and its return value is passed to *
2630
* VB_Vector::checkGSLStatus(). If the return value is non-zero, then *
2631
* a error occurred with the GSL function. VB_Vector::checkGSLStatus()*
2632
* will then process the error by writing out an appropriate error *
2633
* message and then causing this program to exit. *
2634
*********************************************************************/
2635
VB_Vector::checkGSLStatus(gsl_vector_mul(this->theVector, V.theVector),
2636
__LINE__, __FILE__, __FUNCTION__);
2638
/*********************************************************************
2639
* Now returning a reference to this instance of VB_Vector. *
2640
*********************************************************************/
2643
} // VB_Vector& VB_Vector::operator*=(const VB_Vector& V)
2645
/*********************************************************************
2646
* This overloaded operator divides each element of this instance *
2647
* of VB_Vector by the corresponding element of the input vector, in *
2649
*********************************************************************/
2650
VB_Vector& VB_Vector::operator/=(const VB_Vector& V)
2653
/*********************************************************************
2654
* gsl_vector_div() is called to do the element by element division *
2655
* and its return value is passed to VB_Vector::checkGSLStatus(). If *
2656
* the return value is non-zero, then a error occurred with the GSL *
2657
* function. VB_Vector::checkGSLStatus() will then process the error *
2658
* by writing out an appropriate error message and then causing this *
2659
* program to exit. *
2660
*********************************************************************/
2661
VB_Vector::checkGSLStatus(gsl_vector_div(this->theVector, V.theVector),
2662
__LINE__, __FILE__, __FUNCTION__);
2664
/*********************************************************************
2665
* VB_Vector::checkFiniteness() is called to ensure that all elements *
2666
* of this->theVector are finite, i.e., no Inf's nor Nan's. *
2667
*********************************************************************/
2668
VB_Vector::checkFiniteness(this->theVector, __LINE__, __FILE__, __FUNCTION__);
2670
/*********************************************************************
2671
* Now returning a reference to this instance of VB_Vector. *
2672
*********************************************************************/
2675
} // VB_Vector& VB_Vector::operator/=(const VB_Vector& V)
2677
/*********************************************************************
2678
* This overloaded operator adds the input vector to this instance of *
2679
* VB_Vector, in place. *
2680
*********************************************************************/
2681
VB_Vector& VB_Vector::operator+=(const VB_Vector *V)
2684
/*********************************************************************
2685
* gsl_vector_add() is called to compute the vector sum and its *
2686
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2687
* return value is non-zero, then a error occurred with the GSL *
2688
* function. VB_Vector::checkGSLStatus() will then process the error *
2689
* by writing out an appropriate error message and then causing this *
2690
* program to exit. *
2691
*********************************************************************/
2692
VB_Vector::checkGSLStatus(gsl_vector_add(this->theVector, V->theVector),
2693
__LINE__, __FILE__, __FUNCTION__);
2695
/*********************************************************************
2696
* Now returning a reference to this instance of VB_Vector. *
2697
*********************************************************************/
2700
} // VB_Vector& VB_Vector::operator+=(const VB_Vector *V)
2702
/*********************************************************************
2703
* This overloaded operator subtracts the input vector from this *
2704
* instance of VB_Vector, in place. *
2705
*********************************************************************/
2706
VB_Vector& VB_Vector::operator-=(const VB_Vector *V)
2709
/*********************************************************************
2710
* gsl_vector_sub() is called to compute the vector difference and its*
2711
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2712
* return value is non-zero, then a error occurred with the GSL *
2713
* function. VB_Vector::checkGSLStatus() will then process the error *
2714
* by writing out an appropriate error message and then causing this *
2715
* program to exit. *
2716
*********************************************************************/
2717
VB_Vector::checkGSLStatus(gsl_vector_sub(this->theVector, V->theVector),
2718
__LINE__, __FILE__, __FUNCTION__);
2720
/*********************************************************************
2721
* Now returning a reference to this instance of VB_Vector. *
2722
*********************************************************************/
2725
} // VB_Vector& VB_Vector::operator-=(const VB_Vector *V)
2727
/*********************************************************************
2728
* This overloaded operator multiplies each element of this instance *
2729
* of VB_Vector by the corresponding element of the input vector, in *
2731
*********************************************************************/
2732
VB_Vector& VB_Vector::operator*=(const VB_Vector *V)
2735
/*********************************************************************
2736
* gsl_vector_mul() is called to compute the element by element *
2737
* product and its return value is passed to *
2738
* VB_Vector::checkGSLStatus(). If the return value is non-zero, then *
2739
* a error occurred with the GSL function. VB_Vector::checkGSLStatus()*
2740
* will then process the error by writing out an appropriate error *
2741
* message and then causing this program to exit. *
2742
*********************************************************************/
2743
VB_Vector::checkGSLStatus(gsl_vector_mul(this->theVector, V->theVector),
2744
__LINE__, __FILE__, __FUNCTION__);
2746
/*********************************************************************
2747
* Now returning a reference to this instance of VB_Vector. *
2748
*********************************************************************/
2751
} // VB_Vector& VB_Vector::operator*=(const VB_Vector *V)
2753
/*********************************************************************
2754
* This overloaded operator divides each element of this instance *
2755
* of VB_Vector by the corresponding element of the input vector, in *
2757
*********************************************************************/
2758
VB_Vector& VB_Vector::operator/=(const VB_Vector *V)
2761
/*********************************************************************
2762
* gsl_vector_div() is called to do the element by element division *
2763
* and its return value is passed to VB_Vector::checkGSLStatus(). If *
2764
* the return value is non-zero, then a error occurred with the GSL *
2765
* function. VB_Vector::checkGSLStatus() will then process the error *
2766
* by writing out an appropriate error message and then causing this *
2767
* program to exit. *
2768
*********************************************************************/
2769
VB_Vector::checkGSLStatus(gsl_vector_div(this->theVector, V->theVector),
2770
__LINE__, __FILE__, __FUNCTION__);
2772
/*********************************************************************
2773
* VB_Vector::checkFiniteness() is called to ensure that all elements *
2774
* of this->theVector are finite, i.e., no Inf's nor Nan's. *
2775
*********************************************************************/
2776
VB_Vector::checkFiniteness(this->theVector, __LINE__, __FILE__, __FUNCTION__);
2778
/*********************************************************************
2779
* Now returning a reference to this instance of VB_Vector. *
2780
*********************************************************************/
2783
} // VB_Vector& VB_Vector::operator/=(const VB_Vector *V)
2785
/*********************************************************************
2786
* This overloaded operator adds the input vector to this instance of *
2787
* VB_Vector, in place. *
2788
*********************************************************************/
2789
VB_Vector& VB_Vector::operator+=(const gsl_vector *V)
2792
/*********************************************************************
2793
* gsl_vector_add() is called to compute the vector sum and its *
2794
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2795
* return value is non-zero, then a error occurred with the GSL *
2796
* function. VB_Vector::checkGSLStatus() will then process the error *
2797
* by writing out an appropriate error message and then causing this *
2798
* program to exit. *
2799
*********************************************************************/
2800
VB_Vector::checkGSLStatus(gsl_vector_add(this->theVector, V),
2801
__LINE__, __FILE__, __FUNCTION__);
2803
/*********************************************************************
2804
* Now returning a reference to this instance of VB_Vector. *
2805
*********************************************************************/
2808
} // VB_Vector& VB_Vector::operator+=(const gsl_vector *V)
2810
/*********************************************************************
2811
* This overloaded operator subtracts the input vector from this *
2812
* instance of VB_Vector, in place. *
2813
*********************************************************************/
2814
VB_Vector& VB_Vector::operator-=(const gsl_vector *V)
2817
/*********************************************************************
2818
* gsl_vector_sub() is called to compute the vector difference and its*
2819
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2820
* return value is non-zero, then a error occurred with the GSL *
2821
* function. VB_Vector::checkGSLStatus() will then process the error *
2822
* by writing out an appropriate error message and then causing this *
2823
* program to exit. *
2824
*********************************************************************/
2825
VB_Vector::checkGSLStatus(gsl_vector_sub(this->theVector, V),
2826
__LINE__, __FILE__, __FUNCTION__);
2828
/*********************************************************************
2829
* Now returning a reference to this instance of VB_Vector. *
2830
*********************************************************************/
2833
} // VB_Vector& VB_Vector::operator-=(const gsl_vector *V)
2835
/*********************************************************************
2836
* This overloaded operator multiplies each element of this instance *
2837
* of VB_Vector by the corresponding element of the input vector, in *
2839
*********************************************************************/
2840
VB_Vector& VB_Vector::operator*=(const gsl_vector *V)
2843
/*********************************************************************
2844
* gsl_vector_mul() is called to compute the element by element *
2845
* product and its return value is passed to *
2846
* VB_Vector::checkGSLStatus(). If the return value is non-zero, then *
2847
* a error occurred with the GSL function. VB_Vector::checkGSLStatus()*
2848
* will then process the error by writing out an appropriate error *
2849
* message and then causing this program to exit. *
2850
*********************************************************************/
2851
VB_Vector::checkGSLStatus(gsl_vector_mul(this->theVector, V),
2852
__LINE__, __FILE__, __FUNCTION__);
2854
/*********************************************************************
2855
* Now returning a reference to this instance of VB_Vector. *
2856
*********************************************************************/
2859
} // VB_Vector& VB_Vector::operator*=(const gsl_vector *V)
2861
/*********************************************************************
2862
* This overloaded operator divides each element of this instance *
2863
* of VB_Vector by the corresponding element of the input vector, in *
2865
*********************************************************************/
2866
VB_Vector& VB_Vector::operator/=(const gsl_vector *V)
2869
/*********************************************************************
2870
* gsl_vector_div() is called to do the element by element division *
2871
* and its return value is passed to VB_Vector::checkGSLStatus(). If *
2872
* the return value is non-zero, then a error occurred with the GSL *
2873
* function. VB_Vector::checkGSLStatus() will then process the error *
2874
* by writing out an appropriate error message and then causing this *
2875
* program to exit. *
2876
*********************************************************************/
2877
VB_Vector::checkGSLStatus(gsl_vector_div(this->theVector, V),
2878
__LINE__, __FILE__, __FUNCTION__);
2880
/*********************************************************************
2881
* VB_Vector::checkFiniteness() is called to ensure that all elements *
2882
* of this->theVector are finite, i.e., no Inf's nor Nan's. *
2883
*********************************************************************/
2884
VB_Vector::checkFiniteness(this->theVector, __LINE__, __FILE__, __FUNCTION__);
2886
/*********************************************************************
2887
* Now returning a reference to this instance of VB_Vector. *
2888
*********************************************************************/
2891
} // VB_Vector& VB_Vector::operator/=(const gsl_vector *V)
2893
/*********************************************************************
2894
* This overloaded operator adds the input vector to this instance of *
2895
* VB_Vector, in place. *
2896
*********************************************************************/
2897
VB_Vector& VB_Vector::operator+=(const gsl_vector& V)
2900
/*********************************************************************
2901
* gsl_vector_add() is called to compute the vector sum and its *
2902
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2903
* return value is non-zero, then a error occurred with the GSL *
2904
* function. VB_Vector::checkGSLStatus() will then process the error *
2905
* by writing out an appropriate error message and then causing this *
2906
* program to exit. *
2907
*********************************************************************/
2908
VB_Vector::checkGSLStatus(gsl_vector_add(this->theVector, (&V)),
2909
__LINE__, __FILE__, __FUNCTION__);
2911
/*********************************************************************
2912
* Now returning a reference to this instance of VB_Vector. *
2913
*********************************************************************/
2916
} // VB_Vector& VB_Vector::operator+=(const gsl_vector& V)
2918
/*********************************************************************
2919
* This overloaded operator subtracts the input vector from this *
2920
* instance of VB_Vector, in place. *
2921
*********************************************************************/
2922
VB_Vector& VB_Vector::operator-=(const gsl_vector& V)
2925
/*********************************************************************
2926
* gsl_vector_sub() is called to compute the vector difference and its*
2927
* return value is passed to VB_Vector::checkGSLStatus(). If the *
2928
* return value is non-zero, then a error occurred with the GSL *
2929
* function. VB_Vector::checkGSLStatus() will then process the error *
2930
* by writing out an appropriate error message and then causing this *
2931
* program to exit. *
2932
*********************************************************************/
2933
VB_Vector::checkGSLStatus(gsl_vector_sub(this->theVector, (&V)),
2934
__LINE__, __FILE__, __FUNCTION__);
2936
/*********************************************************************
2937
* Now returning a reference to this instance of VB_Vector. *
2938
*********************************************************************/
2941
} // VB_Vector& VB_Vector::operator-=(const gsl_vector& V)
2943
/*********************************************************************
2944
* This overloaded operator multiplies each element of this instance *
2945
* of VB_Vector by the corresponding element of the input vector, in *
2947
*********************************************************************/
2948
VB_Vector& VB_Vector::operator*=(const gsl_vector& V)
2951
/*********************************************************************
2952
* gsl_vector_mul() is called to compute the element by element *
2953
* product and its return value is passed to *
2954
* VB_Vector::checkGSLStatus(). If the return value is non-zero, then *
2955
* a error occurred with the GSL function. VB_Vector::checkGSLStatus()*
2956
* will then process the error by writing out an appropriate error *
2957
* message and then causing this program to exit. *
2958
*********************************************************************/
2959
VB_Vector::checkGSLStatus(gsl_vector_mul(this->theVector, (&V)),
2960
__LINE__, __FILE__, __FUNCTION__);
2962
/*********************************************************************
2963
* Now returning a reference to this instance of VB_Vector. *
2964
*********************************************************************/
2967
} // VB_Vector& VB_Vector::operator*=(const gsl_vector& V)
2969
/*********************************************************************
2970
* This overloaded operator divides each element of this instance *
2971
* of VB_Vector by the corresponding element of the input vector, in *
2973
*********************************************************************/
2974
VB_Vector& VB_Vector::operator/=(const gsl_vector& V)
2977
/*********************************************************************
2978
* gsl_vector_div() is called to do the element by element division *
2979
* and its return value is passed to VB_Vector::checkGSLStatus(). If *
2980
* the return value is non-zero, then a error occurred with the GSL *
2981
* function. VB_Vector::checkGSLStatus() will then process the error *
2982
* by writing out an appropriate error message and then causing this *
2983
* program to exit. *
2984
*********************************************************************/
2985
VB_Vector::checkGSLStatus(gsl_vector_div(this->theVector, (&V)),
2986
__LINE__, __FILE__, __FUNCTION__);
2988
/*********************************************************************
2989
* VB_Vector::checkFiniteness() is called to ensure that all elements *
2990
* of this->theVector are finite, i.e., no Inf's nor Nan's. *
2991
*********************************************************************/
2992
VB_Vector::checkFiniteness(this->theVector, __LINE__, __FILE__, __FUNCTION__);
2994
/*********************************************************************
2995
* Now returning a reference to this instance of VB_Vector. *
2996
*********************************************************************/
2999
} // VB_Vector& VB_Vector::operator/=(const gsl_vector& V)
3001
/*********************************************************************
3002
* This instance method populates the input array with the element *
3003
* values from this instance of VB_Vector. It is assumes that the *
3004
* input array, theArray[], has been properly sized, i.e., sufficient *
3005
* memory has been allocated to theArray[], before this method is *
3007
*********************************************************************/
3008
void VB_Vector::fetchData(double *theArray, const size_t length) const
3011
/*********************************************************************
3012
* VB_Vector::checkVectorLengths() is called to see if *
3013
* this->theVector->size equals the input variable length. If they are*
3014
* not equal, then VB_Vector::checkVectorLengths() will display an *
3015
* appropriate error and then cause this program to exit. NOTE: Even *
3016
* this->theVector->size equals length, this is no guarantee that *
3017
* theArray[] has been properly sized. *
3018
*********************************************************************/
3019
VB_Vector::checkVectorLengths(this->getLength(), length, __LINE__,
3020
__FILE__, __FUNCTION__);
3022
/*********************************************************************
3023
* Now copying the elements of this instance of VB_Vector to *
3025
*********************************************************************/
3026
memcpy(theArray, this->theVector->data, length * sizeof(double));
3028
} // void VB_Vector::fetchData(double *theArray, const size_t length) const
3030
/*********************************************************************
3031
* This instance method transforms this instance of VB_Vector into a *
3033
*********************************************************************/
3034
void VB_Vector::unitVector()
3037
/*********************************************************************
3038
* The Euclidean norm is stored in norm. *
3039
*********************************************************************/
3040
double norm = this->euclideanNorm();
3042
/*********************************************************************
3043
* If norm is positive, then we go ahead and make the unit vector. *
3044
*********************************************************************/
3048
/*********************************************************************
3049
* we now save the reciprocal of norm in norm. *
3050
*********************************************************************/
3053
/*********************************************************************
3054
* Now calling this->scaleInPlace() to turn this instance of VB_Vector*
3055
* into a unit vector. *
3056
*********************************************************************/
3057
this->scaleInPlace(norm);
3061
/*********************************************************************
3062
* If program flow ends up here, then we have a zero vector. *
3063
* Therefore, an exception is thrown with an appropriate error *
3065
*********************************************************************/
3069
/*********************************************************************
3070
* Now throwing the exception. *
3071
*********************************************************************/
3072
VB_Vector::zeroVector(norm, __LINE__, __FILE__, __FUNCTION__);
3076
} // void VB_Vector::unitVector()
3078
/*********************************************************************
3079
* This method resizes the vector to the desired new length and all *
3080
* of the vector elements will be set to zero. *
3081
*********************************************************************/
3082
void VB_Vector::resize(size_t newLength)
3085
/*********************************************************************
3086
* If this->theVector is NULL (no gsl_vector was allocated) or if the *
3087
* current size of this instance of VB_Vector is not equal to the *
3088
* new desired length, then a resizing is carried out. *
3089
*********************************************************************/
3090
if (this->theVector==NULL || (this->theVector->size != newLength))
3093
/*********************************************************************
3094
* Calling this->init() to do the resizing. All vector elements will *
3095
* be set to zero. try/catch blocks are used to process any exception *
3096
* thrown by this->init(). *
3097
*********************************************************************/
3100
this->init(newLength);
3102
catch (GenericExcep &e)
3104
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3108
/*********************************************************************
3109
* If program flow ends up here, then this instance of VB_Vector is *
3110
* already of the required size. Therefore, we simply overwrite *
3111
* this->theVector->data with zeroes. *
3112
*********************************************************************/
3113
else if (this->theVector->size == newLength)
3115
memset(this->theVector->data, 0, sizeof(double) * newLength);
3118
} // void VB_Vector::resize(size_t newLength)
3120
/*********************************************************************
3121
* This instance method computes and returns the vector sum. *
3122
*********************************************************************/
3123
double VB_Vector::getVectorSum() const
3127
for (unsigned long i = 0; i < this->getLength(); i++)
3129
sum += this->theVector->data[i];
3133
} // double VB_Vector::getVectorSum() const
3135
/*********************************************************************
3136
* This instance method computes and returns the vector mean. *
3137
*********************************************************************/
3138
double VB_Vector::getVectorMean() const
3141
/*********************************************************************
3142
* Calling the template function getMean() to return the mean. *
3143
*********************************************************************/
3144
return getMean(this->theVector->data, this->getLength());
3146
} // double VB_Vector::getVectorMean() const
3148
/*********************************************************************
3149
* This static method returns the mean of the input gsl_vector. *
3150
*********************************************************************/
3151
double VB_Vector::getVectorMean(const gsl_vector *V)
3154
/*********************************************************************
3155
* Calling the template function getMean() to return the mean. *
3156
*********************************************************************/
3157
return getMean(V->data, V->size);
3159
} // double VB_Vector::getVectorMean(const gsl_vector *V)
3161
/*********************************************************************
3162
* This static method returns the mean of the input gsl_vector. *
3163
*********************************************************************/
3164
double VB_Vector::getVectorMean(const gsl_vector& V)
3167
/*********************************************************************
3168
* Returning the mean. *
3169
*********************************************************************/
3170
return VB_Vector::getVectorMean(&V);
3172
} // double VB_Vector::getVectorMean(const gsl_vector& V)
3174
/*********************************************************************
3175
* This static method returns the mean of the input VB_Vector. *
3176
*********************************************************************/
3177
double VB_Vector::getVectorMean(const VB_Vector& V)
3180
/*********************************************************************
3181
* Returning the mean. *
3182
*********************************************************************/
3183
return VB_Vector::getVectorMean(V.theVector);
3185
} // double VB_Vector::getVectorMean(const VB_Vector& V)
3187
/*********************************************************************
3188
* This static method returns the mean of the input VB_Vector. *
3189
*********************************************************************/
3190
double VB_Vector::getVectorMean(const VB_Vector *V)
3193
/*********************************************************************
3194
* Returning the mean. *
3195
*********************************************************************/
3196
return VB_Vector::getVectorMean(V->theVector);
3198
} // double VB_Vector::getVectorMean(const VB_Vector *V)
3200
/*********************************************************************
3201
* This method convolves this instance of VB_Vector with the input *
3202
* VB_Vector, in place. This method implements the MATLAB style *
3203
* convolution function. *
3204
*********************************************************************/
3205
void VB_Vector::convolve(const VB_Vector& v)
3207
this->convolve(v.theVector);
3208
} // void VB_Vector::convolve(const VB_Vector& v)
3210
/*********************************************************************
3211
* This method convolves this instance of VB_Vector with the input *
3212
* VB_Vector, in place. This method implements the MATLAB style *
3213
* convolution function. *
3214
*********************************************************************/
3215
void VB_Vector::convolve(const VB_Vector *v)
3218
} // void VB_Vector::convolve(const VB_Vector *v)
3220
/*********************************************************************
3221
* This method convolves this instance of VB_Vector with the input *
3222
* gsl_vector, in place. *
3224
* Here is the definition of the convolution used: *
3225
* 1. Let the resulting vector of the convolution of 2 vectors A *
3226
* and B be denoted by: (A, B). *
3227
* 2. Let Az denote the vector A concatenated with a zero vector *
3228
* of the same length as A. Similarly for B. *
3229
* 3. Let the length of A be m and the length of B be n. *
3230
* 4. Let [i] represent the i'th element of a vector. *
3231
* 5. Then (A, B)[k] is given by the sum: *
3237
* \ Az[j] * Bz[k - j] *
3242
* for k = 0, 1, ..., m + n - 2. *
3244
* NOTE: Some texts allow the vector resulting from the convolution *
3245
* to have length (m + n) and not length (m + n - 1) as we do here. *
3246
* However, the last element in this vector of length (m + n) is *
3247
* always zero. This method simply omits this last element that is *
3248
* always zero. This method implements the MATLAB style convolution *
3250
*********************************************************************/
3251
void VB_Vector::convolve(const gsl_vector *kernel)
3254
/*********************************************************************
3255
* Since this method overwrites this instance of VB_Vector with the *
3256
* result of the convolution, we need to save this instance of *
3258
*********************************************************************/
3259
VB_Vector tempVec(this);
3261
/*********************************************************************
3262
* We now resize this instance of VB_Vector to have the required size *
3263
* of the result of the convolution. try/catch blocks are used in *
3264
* case this->init() throws an exception. *
3265
*********************************************************************/
3268
this->init(this->getLength() + kernel->size - 1);
3270
catch (GenericExcep &e)
3272
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3275
/*********************************************************************
3276
* The following for loop indexes the vector resulting from the *
3278
*********************************************************************/
3279
for (size_t k = 0; k < this->getLength(); k++)
3282
/*********************************************************************
3283
* The following for loop is used to compute the k'th element of the *
3284
* convoluted vector. *
3285
*********************************************************************/
3286
for (size_t j = 0; j <= k; j++)
3289
/*********************************************************************
3290
* Recall that the definition of vector convolution used in this *
3291
* method involves concatenating each vector with a zero vector *
3292
* whose length is equal to the length of the vector itself. In order *
3293
* to keep things as efficient as possible, the concatenation of the *
3294
* zero vector was skipped, but we "assume" that each vector was *
3295
* concatenated with a zero vector of appropriate length. However, *
3296
* since neither of the 2 vectors was actually concatenated with a *
3297
* zero vector, we need to check to see if we are actually accessing *
3298
* a valid element in each vector or not. Specifically, when *
3299
* j >= tempVec.theVector->size, tempVec[j] is not a valid in *
3300
* tempVec. Had we actually appeneded a zero vector to tempVec, *
3301
* tempVec[j] (for j >= tempVec.theVector->size and *
3302
* j < (2 * tempVec.theVector->size)) would be a valid element of *
3303
* tempVec and it would equal zero. Similarly for the input vector *
3304
* kernel when (k - j) >= kernel->size and *
3305
* (k - j) < (2 * kernel->size). Therefore, the following if block is *
3306
* is used to ensure that only valid elements of tempVec and kernel *
3307
* are accessed. Doing things this way allows us to skip the step of *
3308
* appending a zero vector to each of the 2 vectors whose convolution *
3309
* we calculate here. *
3310
*********************************************************************/
3311
if ( (j < tempVec.getLength()) && ((k - j) < kernel->size) )
3313
(*this)[k] += tempVec[j] * kernel->data[k - j];
3318
} // void VB_Vector::convolve(const gsl_vector *kernel)
3320
/*********************************************************************
3321
* This method convolves this instance of VB_Vector with the input *
3322
* gsl_vector, in place. This method implements the MATLAB style *
3323
* convolution function. *
3324
*********************************************************************/
3325
void VB_Vector::convolve(const gsl_vector& v)
3328
} // void VB_Vector::convolve(const gsl_vector& v)
3330
/*********************************************************************
3331
* This method convolves this instance of VB_Vector with the input *
3332
* VB_Vector and returns the convolved vector. This method implements *
3333
* the MATLAB style convolution function. *
3334
*********************************************************************/
3335
VB_Vector VB_Vector::convolve2(const VB_Vector& v) const
3338
/*********************************************************************
3339
* A copy of this instance of VB_Vector is saved to vTemp. Then vTemp *
3340
* is convolved with the input VB_Vector. Finally, vTemp is returned. *
3341
*********************************************************************/
3342
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3343
vTemp.convolve(v.theVector);
3346
} // VB_Vector VB_Vector::convolve2(const VB_Vector& v) const
3348
/*********************************************************************
3349
* This method convolves this instance of VB_Vector with the input *
3350
* VB_Vector and returns the convolved vector. This method implements *
3351
* the MATLAB style convolution function. *
3352
*********************************************************************/
3353
VB_Vector VB_Vector::convolve2(const VB_Vector *v) const
3356
/*********************************************************************
3357
* A copy of this instance of VB_Vector is saved to vTemp. Then vTemp *
3358
* is convolved with the input VB_Vector. Finally, vTemp is returned. *
3359
*********************************************************************/
3360
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3361
vTemp.convolve(v->theVector);
3364
} // VB_Vector VB_Vector::convolve2(const VB_Vector *v) const
3366
/*********************************************************************
3367
* This method convolves this instance of VB_Vector with the input *
3368
* gsl_vector and returns the convolved vector. This method implements*
3369
* the MATLAB style convolution function. *
3370
*********************************************************************/
3371
VB_Vector VB_Vector::convolve2(const gsl_vector& v) const
3374
/*********************************************************************
3375
* A copy of this instance of VB_Vector is saved to vTemp. Then vTemp *
3376
* is convolved with the input gsl_vector. Finally, vTemp is returned.*
3377
*********************************************************************/
3378
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3382
} // VB_Vector VB_Vector::convolve2(const gsl_vector& v) const
3384
/*********************************************************************
3385
* This method convolves this instance of VB_Vector with the input *
3386
* gsl_vector and returns the convolved vector. This method implements*
3387
* the MATLAB style convolution function. *
3388
*********************************************************************/
3389
VB_Vector VB_Vector::convolve2(const gsl_vector *v) const
3392
/*********************************************************************
3393
* A copy of this instance of VB_Vector is saved to vTemp. Then vTemp *
3394
* is convolved with the input gsl_vector. Finally, vTemp is returned.*
3395
*********************************************************************/
3396
VB_Vector v2(this); // NOTE: vTemp.fileName is set to this->fileName.
3400
} // VB_Vector VB_Vector::convolve2(const gsl_vector *v) const
3402
/*********************************************************************
3403
* This is a static method that convolves the 2 input gsl_vector *
3404
* variables and returns a VB_Vector. This method implements the *
3405
* MATLAB style convolution function. *
3406
*********************************************************************/
3407
VB_Vector VB_Vector::convolve(const gsl_vector *v1, const gsl_vector *v2)
3410
/*********************************************************************
3411
* vTemp is instantiated from v1 and then convolved with v2. Finally, *
3412
* vTemp is returned. *
3413
*********************************************************************/
3414
VB_Vector vTemp(v1); // NOTE: vTemp.fileName is empty.
3418
} // VB_Vector VB_Vector::convolve(const gsl_vector *v1, const gsl_vector *v2)
3420
/*********************************************************************
3421
* This is a static method that convolves the 2 input gsl_vector *
3422
* variables and returns a VB_Vector. This method implements the *
3423
* MATLAB style convolution function. *
3424
*********************************************************************/
3425
VB_Vector VB_Vector::convolve(const gsl_vector& v1, const gsl_vector& v2)
3428
/*********************************************************************
3429
* Returning the convolution. *
3430
*********************************************************************/
3431
return VB_Vector::convolve(&v1, &v2);
3433
} // VB_Vector VB_Vector::convolve(const gsl_vector& v1, const gsl_vector& v2)
3435
/*********************************************************************
3436
* This is a static method that convolves the 2 input VB_Vector *
3437
* variables and returns a VB_Vector. This method implements the *
3438
* MATLAB style convolution function. *
3439
*********************************************************************/
3440
VB_Vector VB_Vector::convolve(const VB_Vector& v1, const VB_Vector& v2)
3443
/*********************************************************************
3444
* Returning the convolution. *
3445
*********************************************************************/
3446
return VB_Vector::convolve(v1.theVector, v2.theVector);
3448
} // VB_Vector VB_Vector::convolve(const VB_Vector& v1, const VB_Vector& v2)
3450
/*********************************************************************
3451
* This is a static method that convolves the 2 input VB_Vector *
3452
* variables and returns a VB_Vector. This method implements the *
3453
* MATLAB style convolution function. *
3454
*********************************************************************/
3455
VB_Vector VB_Vector::convolve(const VB_Vector *v1, const VB_Vector *v2)
3458
/*********************************************************************
3459
* Returning the convolution. *
3460
*********************************************************************/
3461
return VB_Vector::convolve(v1->theVector, v2->theVector);
3463
} // VB_Vector VB_Vector::convolve(const VB_Vector *v1, const VB_Vector *v2)
3465
/*********************************************************************
3466
* This instance method computes the variance of the vector. *
3467
*********************************************************************/
3468
double VB_Vector::getVariance() const
3471
/*********************************************************************
3472
* variance will hold the variance of the vector. It's initialized to *
3474
*********************************************************************/
3475
double variance = 0.0;
3477
/*********************************************************************
3478
* mean is assigned the vector mean. *
3479
*********************************************************************/
3480
double mean = this->getVectorMean();
3482
/*********************************************************************
3483
* This for loop is used to compute the sum of the square of the *
3484
* difference between each vector element value and the mean value. *
3485
*********************************************************************/
3486
for (size_t i = 0; i < this->theVector->size; i++)
3488
variance += ((*this)[i] - mean) * ((*this)[i] - mean);
3491
/*********************************************************************
3492
* Now returning the variance. *
3493
*********************************************************************/
3494
return variance / (double ) (this->theVector->size - 1);
3496
} // double VB_Vector::getVariance() const
3498
/*********************************************************************
3499
* This instance method makes this instance of VB_Vector have unit *
3501
*********************************************************************/
3502
void VB_Vector::unitVariance()
3505
/*********************************************************************
3506
* stdDev is assigned the standard deviation of the vector. *
3507
*********************************************************************/
3508
double stdDev = sqrt(this->getVariance());
3510
/*********************************************************************
3511
* Variance is computed by using the following formula: *
3516
* sigma^2 = \ x(i) - x *
3517
* / ---------------- *
3521
* where n = the vector size. *
3523
* If the standard deviation is not 0, then the following for loop *
3524
* will normalize this->theVector to have unit variance. *
3525
*********************************************************************/
3531
} // void VB_Vector::unitVariance()
3533
/*********************************************************************
3534
* This instance method returns a VB_Vector with unit variance derived*
3535
* from this instance of VB_Vector. *
3536
*********************************************************************/
3537
VB_Vector VB_Vector::unitVarianceVector() const
3540
/*********************************************************************
3541
* This instance of VB_Vector is assigned to vTemp. Then vTemp is *
3542
* made to have unit variance, after which it is returned. *
3543
*********************************************************************/
3544
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3545
vTemp.unitVariance();
3548
} // VB_Vector VB_Vector::unitVarianceVector() const
3550
/*********************************************************************
3551
* This instance method appends the input VB_Vector to this instance *
3552
* of VB_Vector, in place. *
3553
*********************************************************************/
3554
void VB_Vector::concatenate(const VB_Vector& V)
3557
/*********************************************************************
3558
* Calling this->concatenate(const gsl_vector *) to carry out the *
3559
* concatenation operation. *
3560
*********************************************************************/
3561
this->concatenate(V.theVector);
3563
} // void VB_Vector::concatenate(const VB_Vector& V)
3565
/*********************************************************************
3566
* This instance method appends the input VB_Vector to this instance *
3567
* of VB_Vector, in place. *
3568
*********************************************************************/
3569
void VB_Vector::concatenate(const VB_Vector *V)
3572
/*********************************************************************
3573
* Calling this->concatenate(const gsl_vector *) to carry out the *
3574
* concatenation operation. *
3575
*********************************************************************/
3576
this->concatenate(V->theVector);
3578
} // void VB_Vector::concatenate(const VB_Vector *V)
3580
/*********************************************************************
3581
* This instance method appends the input gsl_vector to this instance *
3582
* of VB_Vector, in place. *
3583
*********************************************************************/
3584
void VB_Vector::concatenate(const gsl_vector& V)
3587
/*********************************************************************
3588
* Calling this->concatenate(const gsl_vector *) to carry out the *
3589
* concatenation operation. *
3590
*********************************************************************/
3591
this->concatenate(&V);
3593
} // void VB_Vector::concatenate(const gsl_vector& V)
3595
/*********************************************************************
3596
* This instance method appends the input gsl_vector to this instance *
3597
* of VB_Vector, in place. *
3598
*********************************************************************/
3599
void VB_Vector::concatenate(const gsl_vector *V)
3603
/*********************************************************************
3604
* If both the vector to be concatenated have positive length: *
3605
*********************************************************************/
3606
if ( (this->theVector != NULL) && (V != NULL) )
3609
/*********************************************************************
3610
* By default, if the memory allocation fails, *
3611
* then gsl_vector_calloc() will invoke the GSL error handler *
3612
* which calls abort(), creating a core dump. To forgo this behavior, *
3613
* the GSL error handler is turned off and the current error handler *
3614
* is stored in VB_Vector::currentGSLErrorHandler. This is *
3615
* accomplished by the call to this->turnOffGSLErrorHandler(). *
3616
*********************************************************************/
3617
this->turnOffGSLErrorHandler();
3619
/*********************************************************************
3620
* It's possible that the gsl_vector data member of this instance of *
3621
* VB_Vector has the same address as V, i.e., this instance of *
3622
* VB_Vector is being concatenated with itself, which we want to *
3623
* allow. Therefore, two temprary gsl_vector structs are allocated. *
3624
* this->theVector will be copied to tempVec and V will be copied to *
3626
*********************************************************************/
3627
gsl_vector *tempVec = gsl_vector_calloc(this->getLength());
3628
gsl_vector *tempVec2 = gsl_vector_calloc(V->size);
3630
/*********************************************************************
3631
* We now restore the standard GSL error handler by calling *
3632
* this->restoreGSLErrorHandler(). *
3633
*********************************************************************/
3634
this->restoreGSLErrorHandler();
3636
/*********************************************************************
3637
* Ensuring that tempVec is non-null. If tempVec is null, then the *
3638
* try/catch will handle the exception thrown by *
3639
* VB_Vector::vectorNull(), which will have an appropriate error *
3640
* message, as given by gsl_strerror(). *
3641
*********************************************************************/
3644
VB_Vector::vectorNull(tempVec);
3646
catch (GenericExcep &e)
3648
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3651
/*********************************************************************
3652
* Ensuring that tempVec2 is non-null. If tempVec2 is null, then the *
3653
* try/catch will handle the exception thrown by *
3654
* VB_Vector::vectorNull(), which will have an appropriate error *
3655
* message, as given by gsl_strerror(). *
3656
*********************************************************************/
3659
VB_Vector::vectorNull(tempVec2);
3661
catch (GenericExcep &e)
3663
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3666
/*********************************************************************
3667
* Copying this->theVector to tempVec. If VB_Vector::GSLVectorMemcpy()*
3668
* throws an exception (which will have an appropriate error message, *
3669
* as determined by gsl_strerror()) then it is be caught here. *
3670
*********************************************************************/
3673
VB_Vector::GSLVectorMemcpy(tempVec, this->theVector);
3675
catch (GenericExcep &e)
3677
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3680
/*********************************************************************
3681
* Copying V to tempVec. If VB_Vector::GSLVectorMemcpy() throws an *
3682
* exception (which will have an appropriate error message, as *
3683
* determined by gsl_strerror()) then it is be caught here. *
3684
*********************************************************************/
3687
VB_Vector::GSLVectorMemcpy(tempVec2, V);
3689
catch (GenericExcep &e)
3691
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3694
/*********************************************************************
3695
* Resizing this->theVector to (this->theVector->size + V->size). If *
3696
* an exception occurrs, which will have an appropriate error message *
3697
* as determined by gsl_strerror(), then it is caught here. *
3698
*********************************************************************/
3701
this->init(this->getLength() + V->size);
3703
catch (GenericExcep &e)
3705
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3708
/*********************************************************************
3709
* Now assigning the values from tempVec to this instance of *
3711
*********************************************************************/
3712
memcpy(this->theVector->data, tempVec->data, sizeof(double) * tempVec->size);
3714
/*********************************************************************
3715
* Now assigning the values from tempVec2 to this instance of *
3717
*********************************************************************/
3718
memcpy(this->theVector->data + tempVec->size, tempVec2->data, sizeof(double) * tempVec2->size);
3720
/*********************************************************************
3721
* Freeing the memory allocated to tempVec and tempVec2. *
3722
*********************************************************************/
3723
gsl_vector_free(tempVec);
3724
gsl_vector_free(tempVec2);
3728
/*********************************************************************
3729
* If V is NULL, then we do nothing since there's no point in *
3730
* concatenating an empty vector to this instance of VB_Vector. *
3731
*********************************************************************/
3736
/*********************************************************************
3737
* If this instance of VB_Vector is empty, i.e., has zero length, or *
3739
*********************************************************************/
3740
else if (this->theVector==NULL) // qq Could this->theVector ever be NULL ?
3743
/*********************************************************************
3744
* By default, if the memory allocation fails, *
3745
* then gsl_vector_calloc() will invoke the GSL error handler *
3746
* which calls abort(), creating a core dump. To forgo this behavior, *
3747
* the GSL error handler is turned off and the current error handler *
3748
* is stored in VB_Vector::currentGSLErrorHandler. This is *
3749
* accomplished by the call to this->turnOffGSLErrorHandler(). *
3750
*********************************************************************/
3751
this->turnOffGSLErrorHandler();
3753
/*********************************************************************
3754
* Allocating sufficient space for this->theVector. *
3755
*********************************************************************/
3756
this->theVector = gsl_vector_calloc(V->size);
3758
/*********************************************************************
3759
* Ensuring that this->theVector is non-null. If this->theVector is *
3760
* NULL, then the try/catch will handle the exception thrown by *
3761
* VB_Vector::vectorNull(), which will have an appropriate error *
3762
* message, as given by gsl_strerror(). *
3763
*********************************************************************/
3766
VB_Vector::vectorNull(this->theVector);
3768
catch (GenericExcep &e)
3770
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3773
/*********************************************************************
3774
* We now restore the standard GSL error handler by calling *
3775
* this->restoreGSLErrorHandler(). *
3776
*********************************************************************/
3777
this->restoreGSLErrorHandler();
3779
/*********************************************************************
3780
* Copying V to tempVec. If VB_Vector::GSLVectorMemcpy() throws an *
3781
* exception (which will have an appropriate error message, as *
3782
* determined by gsl_strerror()) then it is be caught here. *
3783
*********************************************************************/
3786
VB_Vector::GSLVectorMemcpy(this->theVector, V);
3788
catch (GenericExcep &e)
3790
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
3793
/*********************************************************************
3794
* At this point, we have successfully copied V to this->theVector. *
3795
* Therefore, this->valid is set to true. *
3796
*********************************************************************/
3801
} // void VB_Vector::concatenate(const gsl_vector *V)
3803
/*********************************************************************
3804
* This instance method appends the input VB_Vector to this instance *
3805
* of VB_Vector, not in place, and returns the concatenated VB_Vector.*
3806
*********************************************************************/
3807
VB_Vector VB_Vector::concatenate2(const VB_Vector& V) const
3810
/*********************************************************************
3811
* This instance of VB_Vector is saved to vTemp. *
3812
*********************************************************************/
3813
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3815
/*********************************************************************
3816
* Setting vTemp.fileName to the empty string. *
3817
*********************************************************************/
3818
vTemp.fileName = string("");
3820
/*********************************************************************
3821
* Setting this->valid, this->dataType, and this->fileFormat. init() *
3822
* will also assign a new file name to vTemp.fileName. *
3823
*********************************************************************/
3824
vTemp.init(false, vb_double, "ref1");
3826
/*********************************************************************
3827
* The input vector is concatenated to vTemp and then vTemp is *
3829
*********************************************************************/
3830
vTemp.concatenate(V);
3833
} // VB_Vector VB_Vector::concatenate2(const VB_Vector& V) const
3835
/*********************************************************************
3836
* This instance method appends the input VB_Vector to this instance *
3837
* of VB_Vector, not in place, and returns the concatenated VB_Vector.*
3838
*********************************************************************/
3839
VB_Vector VB_Vector::concatenate2(const VB_Vector *V) const
3842
/*********************************************************************
3843
* This instance of VB_Vector is saved to vTemp. *
3844
*********************************************************************/
3845
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3847
/*********************************************************************
3848
* Setting vTemp.fileName to the empty string. *
3849
*********************************************************************/
3850
vTemp.fileName = string("");
3852
/*********************************************************************
3853
* Setting this->valid, this->dataType, and this->fileFormat. init() *
3854
* will also assign a new file name to vTemp.fileName. *
3855
*********************************************************************/
3856
vTemp.init(false, vb_double, "ref1");
3858
/*********************************************************************
3859
* The input vector is concatenated to vTemp and then vTemp is *
3861
*********************************************************************/
3862
vTemp.concatenate(V);
3865
} // VB_Vector VB_Vector::concatenate2(const VB_Vector *V) const
3867
/*********************************************************************
3868
* This instance method appends the input gsl_vector to this instance *
3869
* of VB_Vector, not in place, and returns the concatenated VB_Vector.*
3870
*********************************************************************/
3871
VB_Vector VB_Vector::concatenate2(const gsl_vector *V) const
3874
/*********************************************************************
3875
* This instance of VB_Vector is saved to vTemp. *
3876
*********************************************************************/
3877
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3879
/*********************************************************************
3880
* Setting vTemp.fileName to the empty string. *
3881
*********************************************************************/
3882
vTemp.fileName = string("");
3884
/*********************************************************************
3885
* Setting this->valid, this->dataType, and this->fileFormat. init() *
3886
* will also assign a new file name to vTemp.fileName. *
3887
*********************************************************************/
3888
vTemp.init(false, vb_double, "ref1");
3890
/*********************************************************************
3891
* The input vector is concatenated to vTemp and then vTemp is *
3893
*********************************************************************/
3894
vTemp.concatenate(V);
3897
} // VB_Vector VB_Vector::concatenate2(const gsl_vector *V) const
3899
/*********************************************************************
3900
* This instance method appends the input gsl_vector to this instance *
3901
* of VB_Vector, not in place, and returns the concatenated VB_Vector.*
3902
*********************************************************************/
3903
VB_Vector VB_Vector::concatenate2(const gsl_vector& V) const
3906
/*********************************************************************
3907
* This instance of VB_Vector is saved to vTemp. *
3908
*********************************************************************/
3909
VB_Vector vTemp(this); // NOTE: vTemp.fileName is set to this->fileName.
3911
/*********************************************************************
3912
* Setting vTemp.fileName to the empty string. *
3913
*********************************************************************/
3914
vTemp.fileName = string("");
3916
/*********************************************************************
3917
* Setting this->valid, this->dataType, and this->fileFormat. init() *
3918
* will also assign a new file name to vTemp.fileName. *
3919
*********************************************************************/
3920
vTemp.init(false, vb_double, "ref1");
3922
/*********************************************************************
3923
* The input vector is concatenated to vTemp and then vTemp is *
3925
*********************************************************************/
3926
vTemp.concatenate(V);
3929
} // VB_Vector VB_Vector::concatenate2(const gsl_vector& V) const
3931
/*********************************************************************
3932
* This is a static method that concatenates the 2 input vectors and *
3933
* returns the concatenated vector. *
3934
*********************************************************************/
3935
VB_Vector VB_Vector::concatenate(const VB_Vector& V1, const VB_Vector& V2)
3938
/*********************************************************************
3939
* V1 is saved to vTemp. *
3940
*********************************************************************/
3941
VB_Vector vTemp(V1); // NOTE: vTemp.fileName is set to V1.fileName.
3943
/*********************************************************************
3944
* Setting vTemp.fileName to the empty string. *
3945
*********************************************************************/
3946
vTemp.fileName = string("");
3948
/*********************************************************************
3949
* Setting this->valid, this->dataType, and this->fileFormat. init() *
3950
* will also assign a new file name to vTemp.fileName. *
3951
*********************************************************************/
3952
vTemp.init(false, vb_double, "ref1");
3954
/*********************************************************************
3955
* The input vector is concatenated to vTemp and then vTemp is *
3957
*********************************************************************/
3958
vTemp.concatenate(V2);
3961
} // VB_Vector VB_Vector::concatenate(const VB_Vector& V1, const VB_Vector& V2)
3963
/*********************************************************************
3964
* This is a static method that concatenates the 2 input vectors and *
3965
* returns the concatenated vector. *
3966
*********************************************************************/
3967
VB_Vector VB_Vector::concatenate(const VB_Vector *V1, const VB_Vector *V2)
3970
/*********************************************************************
3971
* V1 is saved to vTemp. *
3972
*********************************************************************/
3973
VB_Vector vTemp(V1); // NOTE: vTemp.fileName is set to V1->fileName.
3975
/*********************************************************************
3976
* Setting vTemp.fileName to the empty string. *
3977
*********************************************************************/
3978
vTemp.fileName = string("");
3980
/*********************************************************************
3981
* Setting this->valid, this->dataType, and this->fileFormat. init() *
3982
* will also assign a new file name to vTemp.fileName. *
3983
*********************************************************************/
3984
vTemp.init(false, vb_double, "ref1");
3986
/*********************************************************************
3987
* The input vector is concatenated to vTemp and then vTemp is *
3989
*********************************************************************/
3990
vTemp.concatenate(V2);
3993
} // VB_Vector VB_Vector::concatenate(const VB_Vector *V1, const VB_Vector *V2)
3995
/*********************************************************************
3996
* This is a static method that concatenates the 2 input vectors and *
3997
* returns the concatenated vector. *
3998
*********************************************************************/
3999
VB_Vector VB_Vector::concatenate(const gsl_vector& V1, const gsl_vector& V2)
4002
/*********************************************************************
4003
* V1 is saved to vTemp. *
4004
*********************************************************************/
4005
VB_Vector vTemp(V1); // NOTE: vTemp.fileName is empty.
4007
/*********************************************************************
4008
* Setting vTemp.fileName to the empty string. *
4009
*********************************************************************/
4010
vTemp.fileName = string("");
4012
/*********************************************************************
4013
* Setting this->valid, this->dataType, and this->fileFormat. init() *
4014
* will also assign a new file name to vTemp.fileName. *
4015
*********************************************************************/
4016
vTemp.init(false, vb_double, "ref1");
4018
/*********************************************************************
4019
* The input vector is concatenated to vTemp and then vTemp is *
4021
*********************************************************************/
4022
vTemp.concatenate(V2);
4025
} // VB_Vector VB_Vector::concatenate(const gsl_vector& V1, const gsl_vector& V2)
4027
/*********************************************************************
4028
* This is a static method that concatenates the 2 input vectors and *
4029
* returns the concatenated vector. *
4030
*********************************************************************/
4031
VB_Vector VB_Vector::concatenate(const gsl_vector *V1, const gsl_vector *V2)
4034
/*********************************************************************
4035
* V1 is saved to vTemp. Then vTemp is concatenated with V1. Finally, *
4036
* vtemp is returned. *
4037
*********************************************************************/
4038
VB_Vector vTemp(V1); // NOTE: vTemp.fileName is empty.
4040
/*********************************************************************
4041
* Setting vTemp.fileName to the empty string. *
4042
*********************************************************************/
4043
vTemp.fileName = string("");
4045
/*********************************************************************
4046
* Setting this->valid, this->dataType, and this->fileFormat. init() *
4047
* will also assign a new file name to vTemp.fileName. *
4048
*********************************************************************/
4049
vTemp.init(false, vb_double, "ref1");
4051
/*********************************************************************
4052
* The input vector is concatenated to vTemp and then vTemp is *
4054
*********************************************************************/
4055
vTemp.concatenate(V2);
4058
} // VB_Vector VB_Vector::concatenate(const gsl_vector *V1, const gsl_vector *V2)
4060
/*********************************************************************
4061
* This is the overloaded left shift operator. The last i elements *
4062
* from the right are set to zero. *
4063
*********************************************************************/
4064
VB_Vector& VB_Vector::operator<<(size_t i)
4067
/*********************************************************************
4068
* If i is zero, i.e., no shift, then (*this) is simply returned. *
4069
*********************************************************************/
4075
/*********************************************************************
4076
* If i equals or exceeds the length of this vector, then the vector *
4077
* is simply set to all zeros. *
4078
*********************************************************************/
4079
if (i >= this->getLength())
4081
this->init(this->getLength());
4085
/*********************************************************************
4086
* This for loop translates the elements of this instance of VB_Vector*
4087
* i spots to the left. *
4088
*********************************************************************/
4089
for (size_t j = 0; j < this->getLength() - i; j++)
4091
(*this)[j] = (*this)[j + i];
4094
/*********************************************************************
4095
* This for loop sets the last i right hand side elements of this *
4096
* instance of VB_Vector to zero. *
4097
*********************************************************************/
4098
for (size_t j = this->getLength() - i; j < this->getLength(); j++)
4103
/*********************************************************************
4104
* Now returning this instance of VB_Vector. *
4105
*********************************************************************/
4108
} // VB_Vector& VB_Vector::operator<<(size_t i)
4110
/*********************************************************************
4111
* This is the overloaded right shift operator. The first i elements *
4112
* from the left are set to zero. *
4113
*********************************************************************/
4114
VB_Vector& VB_Vector::operator>>(size_t i)
4117
/*********************************************************************
4118
* If i is zero, i.e., no shift, then (*this) is simply returned. *
4119
*********************************************************************/
4125
/*********************************************************************
4126
* If i equals or exceeds the length of this vector, then the vector *
4127
* is simply set to all zeros. *
4128
*********************************************************************/
4129
if (i >= this->getLength())
4131
this->init(this->getLength());
4135
/*********************************************************************
4136
* This for loop translates the elements of this instance of VB_Vector*
4137
* i spots to the right. First we need to make a copy of this *
4138
* instance of VB_Vector since its elements get overwritten from the *
4140
*********************************************************************/
4141
VB_Vector tempVec(this);
4142
for (size_t j = i; j < this->getLength(); j++)
4144
(*this)[j] = tempVec[j - i];
4147
/*********************************************************************
4148
* This for loop sets the first i left hand side elements of this *
4149
* instance of VB_Vector to zero. *
4150
*********************************************************************/
4151
for (size_t j = 0; j < i; j++)
4156
/*********************************************************************
4157
* Now returning this instance of VB_Vector. *
4158
*********************************************************************/
4161
} // VB_Vector& VB_Vector::operator>>(size_t i)
4163
/*********************************************************************
4164
* This overloaed operator scales this instance of VB_Vector by the *
4165
* input alpha and returns the scaled vector. *
4166
*********************************************************************/
4167
VB_Vector VB_Vector::operator*(const double alpha) const
4170
/*********************************************************************
4171
* A copy is made of this instance of VB_Vector. *
4172
*********************************************************************/
4173
VB_Vector tempVec(this);
4175
/*********************************************************************
4176
* gsl_vector_scale() is called to do the scaling and its *
4177
* return value is passed to VB_Vector::checkGSLStatus(). If the *
4178
* return value is non-zero, then a error occurred with the GSL *
4179
* function. VB_Vector::checkGSLStatus() will then process the error *
4180
* by writing out an appropriate error message and then causing this *
4181
* program to exit. *
4182
*********************************************************************/
4183
VB_Vector::checkGSLStatus(gsl_vector_scale(tempVec.theVector, alpha),
4184
__LINE__, __FILE__, __FUNCTION__);
4186
/*********************************************************************
4187
* Now returning the scaled vector. *
4188
*********************************************************************/
4191
} // VB_Vector VB_Vector::operator*(const double alpha) const
4193
/*********************************************************************
4194
* This friend function scales the input VB_Vector by the input *
4195
* double. This function is implemented to preserve commutativity. *
4196
*********************************************************************/
4197
VB_Vector operator*(const double alpha, const VB_Vector& V)
4200
/*********************************************************************
4201
* The copy constructor is used to make a copy of V. *
4202
*********************************************************************/
4203
VB_Vector tempVec(V);
4205
/*********************************************************************
4206
* gsl_vector_scale() is called to do the scaling and its *
4207
* return value is passed to VB_Vector::checkGSLStatus(). If the *
4208
* return value is non-zero, then a error occurred with the GSL *
4209
* function. VB_Vector::checkGSLStatus() will then process the error *
4210
* by writing out an appropriate error message and then causing this *
4211
* program to exit. *
4212
*********************************************************************/
4213
VB_Vector::checkGSLStatus(gsl_vector_scale(tempVec.theVector, alpha),
4214
__LINE__, __FILE__, __FUNCTION__);
4215
/*********************************************************************
4216
* tempVec is scaled by alpha and then returned. *
4217
*********************************************************************/
4218
/* tempVec.scaleInPlace(alpha);*/
4221
} // VB_Vector operator*(const double alpha, const VB_Vector& V)
4225
VB_Vector::meanCenter()
4227
(*this) -= this->getVectorMean();
4230
/*********************************************************************
4231
* This method resets the elements of this instance of VB_Vector from *
4232
* the input array of doubles. The input variable length is assumed *
4233
* to be the length of the array theData. *
4234
*********************************************************************/
4235
void VB_Vector::setData(const double *theData, const size_t length)
4238
/*********************************************************************
4239
* We call this->init() to resize this instance of VB_Vector and *
4240
* catch its exception, if one is thrown. *
4241
*********************************************************************/
4246
catch (GenericExcep &e)
4248
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
4251
memcpy(this->theVector->data, theData, sizeof(double) * length);
4253
} // void VB_Vector::setData(const double *theData, const size_t length)
4255
/*********************************************************************
4256
* This method resets the data values of this instance of VB_Vector *
4257
* from the data values of the input gsl_vector. *
4258
*********************************************************************/
4259
void VB_Vector::setData(const gsl_vector *v)
4262
/*********************************************************************
4263
* Calling this->setData(const double *, const size_t) to reset the *
4265
*********************************************************************/
4266
this->setData(v->data, v->size);
4268
} // void VB_Vector::setData(const gsl_vector *v)
4270
/*********************************************************************
4271
* This method reset the data values of this instance of VB_Vector *
4272
* from the data values of the input gsl_vector. *
4273
*********************************************************************/
4274
void VB_Vector::setData(const gsl_vector& v)
4277
/*********************************************************************
4278
* Calling this->setData(const double *, const size_t) to reset the *
4280
*********************************************************************/
4281
this->setData(v.data, v.size);
4283
} // void VB_Vector::setData(const gsl_vector& v)
4285
/*********************************************************************
4286
* This method reset the data values of this instance of VB_Vector *
4287
* from the data values of the input VB_Vector. *
4288
*********************************************************************/
4289
void VB_Vector::setData(const VB_Vector *V)
4292
/*********************************************************************
4293
* Calling this->setData(const double *, const size_t) to reset the *
4295
*********************************************************************/
4296
this->setData(V->theVector->data, V->getLength());
4298
} // void VB_Vector::setData(const VB_Vector *V)
4300
/*********************************************************************
4301
* This method reset the data values of this instance of VB_Vector *
4302
* from the data values of the input VB_Vector. *
4303
*********************************************************************/
4304
void VB_Vector::setData(const VB_Vector& V)
4307
/*********************************************************************
4308
* Calling this->setData(const double *, const size_t) to reset the *
4310
*********************************************************************/
4311
this->setData(V.theVector->data, V.getLength());
4313
} // void VB_Vector::setData(const VB_Vector& V)
4315
/*********************************************************************
4316
* This method multiplies this instance of VB_Vector by the *
4317
* orthogonal projector: *
4320
* (I - A (A A) A ) *
4324
* A is the matrix created from the VB_Vector's found in the *
4325
* argument reference. *
4326
* I is an appropriately dimensioned identity matrix. *
4328
* Basically, if this instance of VB_Vector is denoted by x, then *
4329
* the following computation is carried out: *
4332
* x' = (I - A (A A) A )x *
4334
* where x' is this instance of VB_Vector after all the computations *
4335
* have been carried out. *
4337
* To implement the computations in an efficient manner as possible, *
4338
* the following steps are carried out (assume A is (m x n) and that *
4342
* 1. Let v = A x (v is then (n x 1)) *
4344
* ==> x' = x - A (A A) v *
4347
* 2. Let y = (A A) v (y is (n x 1)) *
4348
* This linear system will be solved for y (this saves us the *
4349
* computationally expensive step of computing a matrix inverse). *
4353
* NOTE: It is expected that A has linearly independent columns. *
4354
*********************************************************************/
4355
void VB_Vector::orthogonalize(const vector<VB_Vector> reference)
4358
/*********************************************************************
4359
* We now see if the input variable reference represents an *
4360
* overdetermined system or not. If it does, then an exception is *
4361
* thrown (by calling VB_Vector::createException()) and then caught. *
4362
* An error message is assembled first. *
4363
*********************************************************************/
4364
if (this->getLength() < reference.size())
4367
/*********************************************************************
4368
* errorMsg[] will hold the error message that the index is out of *
4370
*********************************************************************/
4371
char errorMsg[OPT_STRING_LENGTH];
4372
memset(errorMsg, 0, OPT_STRING_LENGTH);
4374
/*********************************************************************
4375
* Populating errorMsg[] with the appropriate error message. *
4376
*********************************************************************/
4377
sprintf(errorMsg, "The vector length [%d] is < the number of column vectors [%d] (overdetermined system).",
4378
(int)(this->getLength()), (int)(reference.size()));
4380
/*********************************************************************
4381
* Now calling VB_Vector::createException() to throw and catch the *
4383
*********************************************************************/
4384
VB_Vector::createException(errorMsg, __LINE__, __FILE__, __FUNCTION__);
4388
/*********************************************************************
4389
* By default, if the memory allocation fails, *
4390
* then gsl_matrix_calloc() (called by this->initMatrix()) will invoke*
4391
* the GSL error handler which calls abort(), creating a core dump. *
4392
* To forgo this behavior, the GSL error handler is turned off and *
4393
* the current error handler is stored in *
4394
* VB_Vector::currentGSLErrorHandler. This is accomplished by the *
4395
* call to this->turnOffGSLErrorHandler(). *
4396
*********************************************************************/
4397
this->turnOffGSLErrorHandler();
4399
/*********************************************************************
4400
* Allocating a gsl_matrix with rows reference[0].getLength() and *
4401
* columns reference.size(). All the elements in the gsl_matrix will *
4402
* be initialized to 0. try/catch blocks are used to process the *
4403
* exception that may be thrown by this->initMatrix(). *
4404
*********************************************************************/
4405
gsl_matrix *A = NULL;
4408
A = this->initMatrix(reference[0].getLength(), reference.size());
4410
catch (GenericExcep &e)
4412
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
4415
/*********************************************************************
4416
* Now allocating a gsl_matrix struct correctly dimensioned to hold *
4418
* the product of A and A. All its elements will be initialized to 0.*
4419
* try/catch blocks are used to process the exception that may be *
4420
* thrown by this->initMatrix(). *
4421
*********************************************************************/
4422
gsl_matrix *aTa = NULL;
4425
aTa = this->initMatrix(reference.size(), reference.size());
4427
catch (GenericExcep &e)
4429
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
4432
/*********************************************************************
4433
* We now populate A with the VB_Vectors from reference. Each *
4434
* VB_Vector from reference is seen as a column vector of A. If *
4435
* gsl_matrix_set_col() returns a non-zero return value, then an *
4436
* error occurred, which is handled by checkGSLStatus(). *
4437
*********************************************************************/
4438
for (size_t i = 0; i < reference.size(); i++)
4440
VB_Vector::checkGSLStatus(gsl_matrix_set_col(A, i, reference[i].getTheVector()), __LINE__, __FILE__, __FUNCTION__);
4443
/*********************************************************************
4445
* v will be used to hold the matrix-vector product A x. Since A is *
4446
* (m x n) and x is (m x 1), v needs to have length n, which is the *
4447
* number of columns in A, found in the field A->size2. *
4448
*********************************************************************/
4449
VB_Vector v(A->size2);
4451
/*********************************************************************
4452
* Now carrying out the matrix-vector multiplication (Ax). The product*
4453
* will be stored in v. The prototype for the function *
4454
* gsl_blas_dgemv() is: *
4456
* int gsl_blas_dgemv (CBLAS_TRANSPOSE_t TransA, *
4458
* const gsl_matrix * A, *
4459
* const gsl_vector * x, *
4461
* gsl_vector * y); *
4463
* and the actual operations carried out by gsl_blas_dgemv() are: *
4465
* y := alpha (op(A)) x + beta (y) *
4469
* A if TransA is CblasTrans *
4470
* A if TransA is CblasNoTrans *
4472
* In this specific case, we are simply computing v = (A x). If *
4473
* gsl_blas_dgemv() returns a non-zero value, then an error occurred, *
4474
* which gets handled by checkGSLStatus(). *
4475
*********************************************************************/
4476
VB_Vector::checkGSLStatus(gsl_blas_dgemv(CblasTrans, 1.0, A, this->theVector, 0.0, v.theVector),
4477
__LINE__, __FILE__, __FUNCTION__);
4479
/*********************************************************************
4481
* Now carrying out the matrix multiplication (A * A). The product *
4482
* will be stored in aTa. The prototype for the function *
4483
* gsl_blas_dgemm() is: *
4485
* int gsl_blas_dgemm (CBLAS_TRANSPOSE_t TransA, *
4486
* CBLAS_TRANSPOSE_t TransB, *
4488
* const gsl_matrix * A, *
4489
* const gsl_matrix * B, *
4491
* gsl_matrix * C); *
4493
* and the actual operations carried out by gsl_blas_dgemm() are: *
4495
* C := alpha * op(A) * op(B) + beta * C *
4499
* A if TransA is CblasTrans *
4500
* A if TransA is CblasNoTrans *
4501
* Similarly for op(B). *
4503
* In this specific case, we are simply computing aTa = A A. *
4504
*********************************************************************/
4505
VB_Vector::checkGSLStatus(gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, A, A, 0.0, aTa),
4506
__LINE__, __FILE__, __FUNCTION__);
4508
/*********************************************************************
4509
* As the second step, we use gsl_linalg_cholesky_decomp() to compute *
4510
* Cholesky factorization of aTa (since is is expected that the *
4511
* columns of A are linearly independent, aTa will be positive *
4512
* definite). After gsl_linalg_cholesky_decomp(), aTa will hold the *
4513
* Cholesky factors. checkGSLStatus() is used to process any non-zero *
4514
* value, i.e., an error, returned by gsl_linalg_cholesky_decomp(). *
4515
*********************************************************************/
4516
VB_Vector::checkGSLStatus(gsl_linalg_cholesky_decomp(aTa),
4517
__LINE__, __FILE__, __FUNCTION__);
4519
/*********************************************************************
4521
* We need to find the vector y such that y = (A A) v. We will do *
4522
* this by solving the linear system: *
4525
* This is why we previously computed the Cholesky factorization of *
4528
* y is initialized to be a vector of length aTa->size1 and all of *
4529
* its elements will be 0. *
4530
*********************************************************************/
4531
VB_Vector y(aTa->size1);
4533
/*********************************************************************
4534
* Now gsl_linalg_cholesky_solve() is used to solve for y. If *
4535
* gsl_linalg_cholesky_solve() returns a non-zero value, then an error*
4536
* occurred, which gets handled by checkGSLStatus(). *
4537
*********************************************************************/
4538
VB_Vector::checkGSLStatus(gsl_linalg_cholesky_solve(aTa, v.theVector, y.theVector),
4539
__LINE__, __FILE__, __FUNCTION__);
4541
/*********************************************************************
4542
* We now call gsl_blas_dgemv() to do the matrix-vector multiplication*
4543
* (Ay). This product will be contained in v.theVector (since we no *
4544
* longer need v, we can safely overwrite it). However, v needs to be *
4545
* resized to have length A->size1 (the number of rows in A). If *
4546
* gsl_blas_dgemv() returns a non-zero value, then an error occurred, *
4547
* which gets handled by checkGSLStatus(). *
4548
*********************************************************************/
4550
VB_Vector::checkGSLStatus(gsl_blas_dgemv(CblasNoTrans, 1.0, A, y.theVector, 0.0, v.theVector),
4551
__LINE__, __FILE__, __FUNCTION__);
4553
/*********************************************************************
4554
* Finally, we now subtract v from this instance of VB_Vector and *
4555
* store the difference in this instance of VB_Vector. *
4556
*********************************************************************/
4559
/*********************************************************************
4560
* We now restore the standard GSL error handler by calling *
4561
* this->restoreGSLErrorHandler(). *
4562
*********************************************************************/
4563
this->restoreGSLErrorHandler();
4565
/*********************************************************************
4566
* Freeing the previously allocated memory for A and aTa. *
4567
*********************************************************************/
4569
gsl_matrix_free(aTa);
4571
} // void VB_Vector::orthogonalize(const vector<VB_Vector> reference)
4573
/*********************************************************************
4574
* This method multiplies the input VB_Vector myVec by the orthogonal *
4578
* (I - A (A A) A ) *
4580
* wehre A is a matrix derived from the inout reference and returns *
4581
* the resulting vector. *
4582
*********************************************************************/
4583
VB_Vector VB_Vector::orthogonalize(const VB_Vector &myVec, const vector<VB_Vector> reference) const
4586
/*********************************************************************
4587
* Instantiating tempVec from myVec. *
4588
*********************************************************************/
4589
VB_Vector tempVec(myVec);
4591
/*********************************************************************
4592
* Multiplying tempVec by the projector and then returning tempVec. *
4593
*********************************************************************/
4594
tempVec.orthogonalize(reference);
4597
} // VB_Vector VB_Vector::orthogonalize(const VB_Vector &myVec, const vector<VB_Vector> reference)
4599
/*********************************************************************
4600
* This static method writes out the input gsl_matrix struct to *
4602
*********************************************************************/
4603
void VB_Vector::printMatrix(const gsl_matrix *M)
4605
/* gsl_matrix_fprintf(stdout, M, "%g");*/
4607
for (size_t i = 0; i < M->size1; i++)
4609
for (size_t j = 0; j < M->size2; j++)
4615
cout << gsl_matrix_get(M, i, j);
4616
if (j != (M->size2 - 1))
4622
cout << " ]" << endl;
4628
} // void VB_Vector::printMatrix(const gsl_matrix *M)
4630
/*********************************************************************
4631
* This static method writes out the input gsl_matrix struct to *
4633
*********************************************************************/
4634
void VB_Vector::printMatrix(const gsl_matrix& M)
4636
VB_Vector::printMatrix(&M);
4637
} // void VB_Vector::printMatrix(const gsl_matrix& M)
4639
/*********************************************************************
4640
* This method computes the FFT of this instance of VB_Vector and *
4641
* stores the real and imaginary parts into the 2 input VB_Vectors. *
4643
* INPUT VARIABLES: TYPE: DESCRIPTION: *
4644
* ---------------- ----- ------------ *
4645
* realPart VB_Vector * Will hold the real part of the *
4647
* imagPart VB_Vector * Will hold the imaginary part of *
4648
* the computed FFT. *
4650
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
4651
* ----------------- ----- ------------ *
4653
*********************************************************************/
4654
void VB_Vector::fft(VB_Vector *realPart, VB_Vector *imagPart) const
4657
/*********************************************************************
4658
* Ensuring that realPart and imagPart are properly sized. *
4659
*********************************************************************/
4660
if (this->getLength() != realPart->getLength())
4662
realPart->resize(this->theVector->size);
4664
if (this->getLength() != imagPart->getLength())
4666
imagPart->resize(this->theVector->size);
4669
/*********************************************************************
4670
* halfSize will be (this->theVector->size / 2) if the length of this *
4671
* instance of VB_Vector is even. Otherwise halfSize will be *
4672
* ((this->theVector->size / 2) - 1). *
4673
*********************************************************************/
4674
const unsigned int halfSize = this->theVector->size / 2;
4676
/*********************************************************************
4677
* even will be true if the length of this instance of VB_Vector is *
4678
* even, false otherwise. *
4679
*********************************************************************/
4680
const bool even = ( (halfSize * 2) == this->theVector->size );
4682
/*********************************************************************
4683
* The data from this instance of VB_Vector is copied to FFT[]. *
4684
*********************************************************************/
4685
double FFT[this->theVector->size];
4686
memcpy(FFT, this->theVector->data, this->theVector->size * sizeof(double));
4688
/*********************************************************************
4689
* The following 2 variables are needed by GSL's *
4690
* gsl_fft_real_transform() function. waveTable is a lookup table for *
4691
* sines and cosines while workSpace is a required work space. *
4692
*********************************************************************/
4693
gsl_fft_real_wavetable *waveTable = gsl_fft_real_wavetable_alloc(this->theVector->size);
4694
gsl_fft_real_workspace *workSpace = gsl_fft_real_workspace_alloc(this->theVector->size);
4696
/*********************************************************************
4697
* If waveTable is NULL, then an exception is thrown and then caught *
4698
* by VB_Vector::createException() to inform the user of this error. *
4699
*********************************************************************/
4702
VB_Vector::createException("Unable to allocate gsl_fft_real_wavetable.", __LINE__, __FILE__, __FUNCTION__);
4705
/*********************************************************************
4706
* If workSpace is NULL, then an exception is thrown and then caught *
4707
* by VB_Vector::createException() to inform the user of this error. *
4708
*********************************************************************/
4711
VB_Vector::createException("Unable to allocate gsl_fft_real_workspace.", __LINE__, __FILE__, __FUNCTION__);
4714
/*********************************************************************
4715
* Now computing the FFT. If the call to gsl_fft_real_transform() is *
4716
* successful, then status will be 0. *
4717
*********************************************************************/
4718
int status = gsl_fft_real_transform(FFT, 1, this->theVector->size, waveTable, workSpace);
4720
/*********************************************************************
4721
* If status is non-zero, then VB_Vector::createException() is called *
4722
* to throw and catch an exception to inform the user of the error. *
4723
* The error message will contain the reason for the error, as *
4724
* returned by gsl_strerror(status). *
4725
*********************************************************************/
4728
VB_Vector::createException(string(gsl_strerror(status) + string(".")), __LINE__, __FILE__, __FUNCTION__);
4731
/*********************************************************************
4732
* We will need to scale FFT[] by the reciprocal of the length of *
4733
* this instance of VB_Vector to make this implementation of the FFT *
4734
* identical to IDL's. To that end, oneOverSize is used to hold the *
4735
* reciprocal of the length of this instance of VB_Vector. *
4736
*********************************************************************/
4737
const double oneOverSize = 1.0 / this->theVector->size;
4739
/*********************************************************************
4740
* FFT[] now holds the discrete Fourier transform of this instance of *
4741
* VB_Vector. However, the storage scheme is not straight forward and *
4742
* is called "half complex." (It's advantage is that it takes the *
4743
* exact same mount of space as the origianl vector.) Here is a *
4744
* descpription of the the "half complex" storage scheme from p. 200 *
4745
* of the GSL Reference Manual: *
4747
* ... the half-complex transform of a real sequence is stored with *
4748
* frequencies in increasing order, starting at zero, with the real *
4749
* and imaginary parts of each frequency in neighboring locations. *
4750
* When a value is know to be real, its imaginary part is not stored. *
4752
* Here are 2 examples, the first is for n = 5 (odd case), the second *
4753
* for n = 6 (even case): *
4755
* complex[0].real = halfcomplex[0] *
4756
* complex[0].imag = 0 (always 0) *
4757
* complex[1].real = halfcomplex[1] *
4758
* complex[1].imag = halfcomplex[2] *
4759
* complex[2].real = halfcomplex[3] *
4760
* complex[2].imag = halfcomplex[4] *
4761
* complex[3].real = halfcomplex[3] *
4762
* complex[3].imag = -halfcomplex[4] *
4763
* complex[4].real = halfcomplex[1] *
4764
* complex[4].imag = -halfcomplex[2] *
4766
* complex[0].real = halfcomplex[0] *
4767
* complex[0].imag = 0 (always 0) *
4768
* complex[1].real = halfcomplex[1] *
4769
* complex[1].imag = halfcomplex[2] *
4770
* complex[2].real = halfcomplex[3] *
4771
* complex[2].imag = halfcomplex[4] *
4772
* complex[3].real = halfcomplex[5] *
4773
* complex[3].imag = 0 (always 0 in even case) *
4774
* complex[4].real = halfcomplex[3] *
4775
* complex[4].imag = -halfcomplex[4] *
4776
* complex[5].real = halfcomplex[1] *
4777
* complex[5].imag = -halfcomplex[2] *
4779
* We will have to "unpack" this half-complex storage to populate *
4780
* realPart[] and imagPart[] with the real and imaginary parts of *
4781
* FFT[]. We now set realPart[0] and imagPart[0]. *
4782
*********************************************************************/
4783
(*realPart)[0] = FFT[0] * oneOverSize;
4784
(*imagPart)[0] = 0.0;
4786
/*********************************************************************
4787
* The following for loop is used to populate the the reaminder of *
4788
* realPart[] and imagPart[] from FFT[]. This for loop also scales *
4789
* the entries of FFT[] by oneOverSize. *
4790
*********************************************************************/
4791
for (unsigned int i = 1; i < this->theVector->size; i++)
4795
(*realPart)[i] = FFT[(2 * i) - 1] * oneOverSize;
4796
(*imagPart)[i] = FFT[(2 * i)] * oneOverSize;
4798
else if (i == halfSize)
4802
(*realPart)[i] = FFT[this->theVector->size - 1] * oneOverSize;
4803
(*imagPart)[i] = 0.0;
4807
(*realPart)[i] = FFT[this->theVector->size - 2] * oneOverSize;
4808
(*imagPart)[i] = FFT[this->theVector->size - 1] * oneOverSize;
4814
/*********************************************************************
4815
* NOTE: Since the index (this->theVector->size - i) is < i, *
4816
* (*realPart)[this->theVector->size - i] has already been scaled by *
4817
* oneOverSize. Similarly for (*imagPart)[this->theVector->size - i]. *
4818
*********************************************************************/
4819
(*realPart)[i] = (*realPart)[this->theVector->size - i];
4820
(*imagPart)[i] = -1.0 * (*imagPart)[this->theVector->size - i];
4826
/*********************************************************************
4827
* Now freeing waveTable and workSpace. *
4828
*********************************************************************/
4829
gsl_fft_real_wavetable_free(waveTable);
4830
gsl_fft_real_workspace_free(workSpace);
4832
} // void VB_Vector::fft(VB_Vector *realPart, VB_Vector *imagPart) const
4834
/*********************************************************************
4835
* This method computes the FFT of this instance of VB_Vector and *
4836
* stores the real and imaginary parts into the 2 input VB_Vectors. *
4838
* INPUT VARIABLES: TYPE: DESCRIPTION: *
4839
* ---------------- ----- ------------ *
4840
* realPart VB_Vector& Will hold the real part of the *
4842
* imagPart VB_Vector& Will hold the imaginary part of *
4843
* the computed FFT. *
4845
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
4846
* ----------------- ----- ------------ *
4848
*********************************************************************/
4849
void VB_Vector::fft(VB_Vector& realPart, VB_Vector& imagPart) const
4852
/*********************************************************************
4853
* We now call this->fft(VB_Vector *realPart, VB_Vector *imagPart). *
4854
*********************************************************************/
4855
this->fft(&realPart, &imagPart);
4857
} // void VB_Vector::fft(VB_Vector& realPart, VB_Vector& imagPart) const
4859
/*********************************************************************
4860
* This method computes the inverse FFT of this instance of VB_Vector *
4861
* and stores the real and imaginary parts into the 2 input *
4864
* INPUT VARIABLES: TYPE: DESCRIPTION: *
4865
* ---------------- ----- ------------ *
4866
* realPart VB_Vector * Will hold the real part of the *
4867
* computed inverse FFT. *
4868
* imagPart VB_Vector * Will hold the imaginary part of *
4869
* the computed inverse FFT. *
4871
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
4872
* ----------------- ----- ------------ *
4874
*********************************************************************/
4875
void VB_Vector::ifft(VB_Vector *realPart, VB_Vector *imagPart) const
4878
/*********************************************************************
4879
* Ensuring that realPart and imagPart are appropriately sized. *
4880
*********************************************************************/
4881
if (this->getLength() != realPart->getLength())
4883
realPart->resize(this->theVector->size);
4885
if (this->getLength() != imagPart->getLength())
4887
imagPart->resize(this->theVector->size);
4890
/*********************************************************************
4891
* status will be used to hold the return status values from the GSL *
4893
*********************************************************************/
4896
/*********************************************************************
4897
* complexVec[] will be a complex representation of the elements of *
4898
* this instance of VB_Vector. Of course, the imaginary parts will *
4899
* all be zero. The real parts will be in the even numbered indexes *
4900
* of complexVec[] and the imaginary parts will be in the odd *
4901
* numbered indexes of complexVec[]. *
4902
*********************************************************************/
4903
double complexVec[this->theVector->size * 2];
4905
/*********************************************************************
4906
* Calling gsl_fft_real_unpack() to populate complexVec[]. *
4907
*********************************************************************/
4908
status = gsl_fft_real_unpack(this->theVector->data, (gsl_complex_packed_array ) complexVec, 1, this->theVector->size);
4910
/*********************************************************************
4911
* If status is non-zero, then VB_Vector::createException() is called *
4912
* to throw and catch an exception to inform the user of the error. *
4913
* The error message will contain the reason for the error, as *
4914
* returned by gsl_strerror(status). *
4915
*********************************************************************/
4918
VB_Vector::createException(string(gsl_strerror(status) + string(".")), __LINE__, __FILE__, __FUNCTION__);
4921
/*********************************************************************
4922
* The following 2 variables are needed by GSL's *
4923
* gsl_fft_complex_backward() function. waveTable is a lookup table *
4924
* for sines and cosines while workSpace is a required work space. *
4925
*********************************************************************/
4926
gsl_fft_complex_wavetable *waveTable = gsl_fft_complex_wavetable_alloc(this->theVector->size);
4927
gsl_fft_complex_workspace *workSpace = gsl_fft_complex_workspace_alloc(this->theVector->size);
4929
/*********************************************************************
4930
* If waveTable is NULL, then an exception is thrown and then caught *
4931
* by VB_Vector::createException() to inform the user of this error. *
4932
*********************************************************************/
4935
VB_Vector::createException("Unable to allocate gsl_fft_complex_wavetable.", __LINE__, __FILE__, __FUNCTION__);
4938
/*********************************************************************
4939
* If workSpace is NULL, then an exception is thrown and then caught *
4940
* by VB_Vector::createException() to inform the user of this error. *
4941
*********************************************************************/
4944
VB_Vector::createException("Unable to allocate gsl_fft_complex_workspace.", __LINE__, __FILE__, __FUNCTION__);
4947
/*********************************************************************
4948
* Now computing the inverse FFT. *
4949
*********************************************************************/
4950
status = gsl_fft_complex_backward(complexVec, 1, this->theVector->size, waveTable, workSpace);
4952
/*********************************************************************
4953
* If status is non-zero, then VB_Vector::createException() is called *
4954
* to throw and catch an exception to inform the user of the error. *
4955
* The error message will contain the reason for the error, as *
4956
* returned by gsl_strerror(status). *
4957
*********************************************************************/
4960
VB_Vector::createException(string(gsl_strerror(status) + string(".")), __LINE__, __FILE__, __FUNCTION__);
4963
/*********************************************************************
4964
* At this point, complexVec[] contains the inverse FFT of this *
4965
* instance of VB_Vector; its even indexed elements holds the real *
4966
* parts and its odd indexed elements holds the imaginary part. Now *
4967
* we populate realPart and imagPart appropriately with the following *
4968
* for loop. i indexes complexVec[] and j indexes realPart and *
4970
*********************************************************************/
4971
for (unsigned int i = 0, j = 0; j < this->theVector->size; j++)
4974
/*********************************************************************
4975
* Assigning the real part of the the j'th complex number from *
4976
* complexVec[] to (*realPart)[j]. Note that i is even and i++ causes *
4978
*********************************************************************/
4979
realPart->theVector->data[j] = complexVec[i++];
4981
/*********************************************************************
4982
* Assigning the imaginary part of the the j'th complex number from *
4983
* complexVec[] to (*imagPart)[j]. Note that i is odd and i++ causes *
4985
*********************************************************************/
4986
imagPart->theVector->data[j] = complexVec[i++];
4990
/*********************************************************************
4991
* Now freeing waveTable and workSpace. *
4992
*********************************************************************/
4993
gsl_fft_complex_wavetable_free(waveTable);
4994
gsl_fft_complex_workspace_free(workSpace);
4996
} // void VB_Vector::ifft(VB_Vector *realPart, VB_Vector *imagPart) const
4998
/*********************************************************************
4999
* This method computes the inverse FFT of this instance of VB_Vector *
5000
* and stores the real and imaginary parts into the 2 input *
5003
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5004
* ---------------- ----- ------------ *
5005
* realPart VB_Vector& Will hold the real part of the *
5006
* computed inverse FFT. *
5007
* imagPart VB_Vector& Will hold the imaginary part of *
5008
* the computed inverse FFT. *
5010
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5011
* ----------------- ----- ------------ *
5013
*********************************************************************/
5014
void VB_Vector::ifft(VB_Vector& realPart, VB_Vector& imagPart) const
5017
/*********************************************************************
5018
* We now call this->ifft(VB_Vector *realPart, VB_Vector *imagPart). *
5019
*********************************************************************/
5020
this->ifft(&realPart, &imagPart);
5022
} // void VB_Vector::ifft(VB_Vector& realPart, VB_Vector& imagPart) const
5024
/*********************************************************************
5025
* Instance method computes the power spectrum of this instance of *
5026
* VB_Vector. This method is derived from VoxBo_Fourier.pro's *
5027
* ReturnPS function. The power spectrum will be stored in result. *
5028
*********************************************************************/
5029
void VB_Vector::getPS(VB_Vector &result) const
5032
/*********************************************************************
5033
* Since we will need the FFT of this instance of VB_Vector, realPart *
5034
* is needed to hold the real part of the FFT and imagPart is need to *
5035
* hold the imaginary part of the FFT. *
5036
*********************************************************************/
5037
VB_Vector realPart(this->getLength());
5038
VB_Vector imagPart(this->getLength());
5040
/*********************************************************************
5041
* Ensuring that result is of the appropriate size. *
5042
*********************************************************************/
5043
if (this->theVector->size != result.theVector->size)
5045
result.resize(this->theVector->size);
5048
/*********************************************************************
5049
* Geting the FFT of this instance of VB_Vector. *
5050
*********************************************************************/
5051
this->fft(realPart, imagPart);
5053
/*********************************************************************
5054
* The following for loop is used to assign the power spectrum values *
5055
* to result. The power spectrum values are computed from: *
5057
* fft(this) * conjugate(fft(this)) *
5059
* where fft(this) is the FFT of this instance of VB_Vector, "*" *
5060
* denotes element-by-element multiplication of the 2 VB_Vector's, *
5061
* and conjuagte() is the complex comjugate of a VB_Vector. *
5062
*********************************************************************/
5063
for (unsigned long i = 0; i < this->theVector->size; i++)
5065
result[i] = (realPart[i] * realPart[i]) + (imagPart[i] * imagPart[i]);
5068
} // void VB_Vector::getPS(VB_Vector &result) const
5070
/*********************************************************************
5071
* Instance method to compute the power spectrum of this instance of *
5072
* VB_Vector. This method is derived from VoxBo_Fourier.pro's *
5073
* ReturnPS function. The power spectrum will be stored in result. *
5074
*********************************************************************/
5075
void VB_Vector::getPS(VB_Vector *result) const
5077
this->getPS(*result);
5078
} // void VB_Vector::getPS(VB_Vector *result) const
5080
/*********************************************************************
5081
* Instance method to compute the power spectrum of this instance of *
5082
* VB_Vector. This method is derived from VoxBo_Fourier.pro's *
5083
* ReturnPS function. *
5084
*********************************************************************/
5085
void VB_Vector::getPS() throw()
5087
VB_Vector tempVec(this->getLength());
5088
this->getPS(tempVec);
5091
} // void VB_Vector::getPS() throw()
5093
/*********************************************************************
5094
* This method simply reverses the vector entries. *
5095
*********************************************************************/
5096
void VB_Vector::reverse()
5099
/*********************************************************************
5100
* Calling gsl_vector_reverse() to carry out the reversing of the *
5101
* vector elements. *
5102
*********************************************************************/
5103
gsl_vector_reverse(this->theVector);
5105
} // void VB_Vector::reverse()
5107
/*********************************************************************
5108
* This static method carries out Sinc Interpolation on the input *
5109
* VB_Vector object. This method is derived from the IDL function *
5110
* SincInterpo, found in VoxBo_Fourier.pro. *
5112
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5113
* ---------------- ----- ------------ *
5114
* timeSeries const VB_Vector& Input VB_Vector object that will*
5115
* be sinc interpolated (this *
5116
* VB_Vector represents a time *
5118
* expFactor int The number of times the original*
5119
* interval is to be expanded. For *
5120
* example, if the interval is 1 *
5121
* second long in the time series, *
5122
* but half second intervals are *
5123
* desired, then expFactor should *
5125
* newSignal VB_Vector& Reference to the VB_Vector *
5126
* object that will hold the result*
5127
* of the sinc interpolation. The *
5129
* (timeseries.getLength() * *
5132
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5133
* ----------------- ----- ------------ *
5135
********************************************************************/
5136
void VB_Vector::sincInterpolation(const VB_Vector& timeSeries,
5137
const unsigned int expFactor, VB_Vector& newSignal)
5140
/*********************************************************************
5141
* If the length of timeSeries is less than 2 (mostly like 1, but *
5142
* could be zero), then an error message is printed and then this *
5144
*********************************************************************/
5145
if (timeSeries.getLength() < 2)
5147
ostringstream errorMsg;
5148
errorMsg << "[" << __FUNCTION__ << "]: Need length to be >= 2. VB_Vector length = ["
5149
<< timeSeries.getLength() << "].";
5150
printErrorMsgAndExit(VB_ERROR, errorMsg.str(), 1);
5153
/*********************************************************************
5154
* length is used to store the length of timeSeries. *
5155
*********************************************************************/
5156
const unsigned long length = timeSeries.getLength();
5158
/*********************************************************************
5159
* Now ensuring that newSignal is properly sized. *
5160
*********************************************************************/
5161
if (newSignal.getLength() != (length * expFactor))
5163
newSignal.resize(length * expFactor);
5166
/*********************************************************************
5167
* We now compute the FFT of timeSeries. realPartFFT is used to hold *
5168
* the real part of timeSeries' FFT. Similarly, imagPartFFT is used *
5169
* to hold the imaginary part of timeSeries' FFT. *
5170
*********************************************************************/
5171
VB_Vector realPartFFT(timeSeries.getLength());
5172
VB_Vector imagPartFFT(timeSeries.getLength());
5173
timeSeries.fft(realPartFFT, imagPartFFT);
5175
/*********************************************************************
5176
* halfLength is the floor of (timeSeries.getLength()/2). *
5177
*********************************************************************/
5178
int halfLength = timeSeries.getLength() / 2;
5180
/*********************************************************************
5181
* phi[] is an array needed to carry out the sinc interpolation. *
5182
* phi[0] will always be zero. The "lower half" values of phi[] will *
5183
* be calculated and the "upper half" values of phi[] depend on its *
5184
* "lower half" values. Specifically, the "lower half" values are *
5185
* computed up to and including phi[halfLength/2]. Then the "lower *
5186
* half" values are reflected about the x-axis, and then about the *
5187
* vertical line y = halfLength. Assume that the x-axis indexes phi[] *
5188
* and the y-axis is phi[i]. When length is 10, the graph of phi[] *
5213
* -----o---+---+---+---+---+---+---+---+---+---+ *
5214
* | 1 2 3 4 5 6 7 8 9 *
5229
*********************************************************************/
5231
memset(phi, 0, sizeof(double) * length);
5233
/*********************************************************************
5234
* The following for loop is used to carry out the remaining work for *
5235
* the sinc interpolation. *
5236
*********************************************************************/
5237
for (unsigned int i = 0; i < expFactor; i++)
5240
/*********************************************************************
5241
* Calculating timeShift. *
5242
*********************************************************************/
5243
double timeShift = (double ) i / (double ) expFactor;
5245
/*********************************************************************
5246
* Even number of values. *
5247
*********************************************************************/
5248
if ( (length % 2) == 0 )
5251
/*********************************************************************
5252
* Now calculating the values for phi[] (for the case of an even *
5253
* number of values in timeSeries[]. *
5254
*********************************************************************/
5255
for (int j = 1; j <= halfLength; j++)
5258
/*********************************************************************
5259
* The following line calculates the "lower half" values of phi[]. *
5260
*********************************************************************/
5261
phi[j] = (timeShift * TWOPI) / ((double ) length / (double ) j);
5263
/*********************************************************************
5264
* When j is not equal to halfLength, then calculate the "upper half" *
5265
* values of phi[]. *
5266
*********************************************************************/
5267
if (j != halfLength)
5269
phi[length - j] = -1.0 * phi[j];
5276
/*********************************************************************
5277
* Odd number of values. *
5278
*********************************************************************/
5282
/*********************************************************************
5283
* Now calculating the values for phi[] (for the case of an odd *
5284
* number of values in timeSeries[]. *
5285
*********************************************************************/
5286
for (int j = 1; j <= halfLength; j++)
5289
/*********************************************************************
5290
* The following line calculates the "lower half" values of phi[]. *
5291
*********************************************************************/
5292
phi[j] = (timeShift * TWOPI) / ((double ) length / (double ) j);
5294
/*********************************************************************
5295
* The following line calculates the "upper half" values of phi[]. *
5296
*********************************************************************/
5297
phi[length - j] = -1.0 * phi[j];
5303
/*********************************************************************
5304
* The elements of shifterReal will hold the real part of the complex *
5305
* product [Complex(cos(phi[j]), sin(phi[j]) * *
5306
* Complex(realPartFFT[j], imagPartFFT[j])], while the elements of *
5307
* shifterImag hold the imaginary part. The following for loop *
5308
* populates both shifterReal and shifterImag. Eventually, we'll need *
5309
* to take the inverse FFT of (shifterReal + i*shifterImag). *
5310
*********************************************************************/
5311
VB_Vector shifterReal(length);
5312
VB_Vector shifterImag(length);
5313
for (unsigned int j = 0; j < length; j++)
5316
/*********************************************************************
5317
* Assigning the value of the jth element of shifterReal and the jth *
5318
* element of shifterImag. *
5319
*********************************************************************/
5320
shifterReal[j] = ((cos(phi[j]) * realPartFFT[j]) -
5321
(sin(phi[j]) * imagPartFFT[j]));
5322
shifterImag[j] = ((cos(phi[j]) * imagPartFFT[j]) +
5323
(sin(phi[j]) * realPartFFT[j]));
5327
/*********************************************************************
5328
* We must view shifterReal and shifterImag as a complex vector, *
5329
* whose jth element is (shifterReal[j] + i*shifterImag[j]). Since we *
5330
* do not have an acutal complex array, the inverse FFT of shifterReal*
5331
* and shifterImag need to be computed separately. To that end, *
5332
* realPartFFTShifter is used to hold the real part of the inverse *
5333
* FFT of shifterReal, imagPartFFTShifter is used to hold the *
5334
* imaginary part of of the inverse FFT of shifterReal; *
5335
* realPartFFTShifterImag is used to hold the real part of the *
5336
* inverse FFT of shifterImag and imagPartFFTShifter is resued to *
5337
* hold the imaginary part of of the inverse FFT of shifterImag (we *
5338
* are not interested in the imaginary part of the inverse FFT's of *
5339
* shifterReal). Ultimately, we will need just the real part of the *
5340
* inverse FFT of the complex vector (shifterReal + i*shifterImag). *
5341
*********************************************************************/
5342
VB_Vector realPartFFTShifter(shifterReal.getLength());
5343
VB_Vector imagPartFFTShifter(shifterReal.getLength());
5344
VB_Vector realPartFFTShifterImag(shifterImag.getLength());
5346
/*********************************************************************
5347
* Now computing the inverse FFT's. *
5348
*********************************************************************/
5349
shifterReal.ifft(realPartFFTShifter, imagPartFFTShifter);
5350
shifterImag.ifft(realPartFFTShifterImag, imagPartFFTShifter);
5352
/*********************************************************************
5353
* Let (a + i*b) be the complex vector representing the inverse FFT *
5354
* of shifterReal. Similarly, let (c + i*d) be the complex vector *
5355
* representing the inverse FFT of shifterImag. Then the real part of *
5356
* the the inverse FFT of the complex vector (shifterReal + *
5357
* i*shifterImag) is represented by the vector (a - d). So now we *
5358
* place the real part in realPartFFTShifter. *
5359
*********************************************************************/
5360
realPartFFTShifter -= imagPartFFTShifter;
5362
/*********************************************************************
5363
* Now the real part of the inverse FFT of the complex vector *
5364
* (shifterReal + i*shifterImag) is assigned to newSignal *
5366
*********************************************************************/
5367
for (unsigned int j = 0; j < length; j++)
5369
newSignal[j * expFactor + i] = realPartFFTShifter[j];
5374
} // void VB_Vector::sincInterpolation(const VB_Vector& timeSeries,
5375
// const unsigned int expFactor, VB_Vector& newSignal)
5377
/*********************************************************************
5378
* This constant instance method carries out Sinc Interpolation on *
5379
* this instance of VB_Vector. This method is derived from the IDL *
5380
* function SincInterpo, found in VoxBo_Fourier.pro. *
5382
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5383
* ---------------- ----- ------------ *
5384
* expFactor int The number of times the original*
5385
* interval is to be expanded. For *
5386
* example, if the interval is 1 *
5387
* second long in the time series, *
5388
* but half second intervals are *
5389
* desired, then expFactor should *
5391
* newSignal VB_Vector& Reference to the VB_Vector *
5392
* object that will hold the result*
5393
* of the sinc interpolation. The *
5395
* (this->getLength() * expFactor).*
5397
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5398
* ----------------- ----- ------------ *
5400
********************************************************************/
5401
void VB_Vector::sincInterpolation(const unsigned int expFactor,
5402
VB_Vector& newSignal) const
5405
/*********************************************************************
5406
* Simply calling the static method to compute the sinc interpolation.*
5407
*********************************************************************/
5408
VB_Vector::sincInterpolation(*this, expFactor, newSignal);
5410
} // void VB_Vector::sincInterpolation(const unsigned int expFactor,
5411
// VB_Vector& newSignal) const
5413
/*********************************************************************
5414
* This non-constant instance method carries out Sinc Interpolation on*
5415
* this instance of VB_Vector. This method is derived from the IDL *
5416
* function SincInterpo, found in VoxBo_Fourier.pro. *
5418
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5419
* ---------------- ----- ------------ *
5420
* expFactor int The number of times the original*
5421
* interval is to be expanded. For *
5422
* example, if the interval is 1 *
5423
* second long in the time series, *
5424
* but half second intervals are *
5425
* desired, then expFactor should *
5428
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5429
* ----------------- ----- ------------ *
5431
********************************************************************/
5432
void VB_Vector::sincInterpolation(const unsigned int expFactor)
5435
/*********************************************************************
5436
* tempVector is a copy of this instance of VB_Vector. newSignal will *
5437
* be used to hold the interpolated signal. *
5438
*********************************************************************/
5439
VB_Vector tempVector(this);
5440
VB_Vector newSignal = VB_Vector();
5442
/*********************************************************************
5443
* Doing the sinc interpolation and then assigning newSignal to this *
5444
* instance of VB_Vector. *
5445
*********************************************************************/
5446
tempVector.sincInterpolation(expFactor, newSignal);
5447
(*this) = newSignal;
5449
} // void VB_Vector::sincInterpolation(const unsigned int expFactor)
5451
/*********************************************************************
5452
* This method is a port of the IDL function PhaseShift, found in *
5453
* VoxBo_Fourier.pro. This method "shifts" a signal in time to *
5454
* provide an output vector that represents the same continuous *
5455
* signal sampled starting either later or earlier. This is *
5456
* accomplished by a simple shift of the phase of the sines that *
5457
* makes up the signal. Recall that a Fourier transform allows for a *
5458
* representation of any signal as the linear combination of *
5459
* sinusoids of different frequencies and phases. Effectively, we will*
5460
* add a constant to the phase of every frequency, shifting the data *
5463
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5464
* ---------------- ----- ------------ *
5465
* tSeries const VB_Vector& The time series to be shifted.*
5467
* timeShift double Number of images to shift to *
5468
* the right, i.e., to lag the *
5469
* signal with respect to the *
5470
* original domain. *
5472
* shiftedSignal VB_Vector& The VB_Vector object that *
5473
* will hold the shifted signal. *
5475
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5476
* ----------------- ----- ------------ *
5477
* shiftedSignal VB_Vector& The shifted signal will be *
5479
********************************************************************/
5480
void VB_Vector::phaseShift(const VB_Vector& tSeries, const double timeShift, VB_Vector& shiftedSignal)
5483
/*********************************************************************
5484
* Making sure that shiftedSignal is appropriately sized. *
5485
*********************************************************************/
5486
if (tSeries.getLength() != shiftedSignal.getLength())
5488
shiftedSignal.resize(tSeries.theVector->size);
5491
/*********************************************************************
5492
* phi[] is an array needed to carry out the phase shift. Now *
5493
* declaring phi[] and setting all of its elements to zero. *
5494
*********************************************************************/
5495
double *phi = new double[tSeries.theVector->size];
5496
memset(phi, 0, sizeof(double) * tSeries.getLength());
5498
/*********************************************************************
5499
* Now calling makePhi() to fill in the values in phi[]. *
5500
*********************************************************************/
5501
VB_Vector::makePhi(phi, tSeries.getLength(), timeShift);
5503
/*********************************************************************
5504
* Now taking the FFT of tSeries[]. realPartFFT is used to hold the *
5505
* real part of the FFT, while imagPartFFT is used to hold the *
5507
*********************************************************************/
5508
VB_Vector realPartFFT = VB_Vector();
5509
VB_Vector imagPartFFT = VB_Vector();
5510
tSeries.fft(realPartFFT, imagPartFFT);
5512
/*********************************************************************
5513
* shifter is the filter by which the signal will be convolved to *
5514
* introduce the phase shift. It is constructed explicitly in the *
5515
* Fourier, i.e., frequency, domain. In the time domain, it may be *
5516
* described as an impulse (delta function) that has been shifted in *
5517
* time by the amount specified by timeShift. shifter is actually *
5518
* instantiated as two VB_Vector objects: shifterReal and shifterImag.*
5519
*********************************************************************/
5520
VB_Vector shifterReal(tSeries.getLength());
5521
VB_Vector shifterImag(tSeries.getLength());
5523
/*********************************************************************
5524
* The following for loop carries out the convolution. *
5525
*********************************************************************/
5526
for (unsigned int i = 0; i < tSeries.getLength(); i++)
5528
shifterReal[i] = (cos(phi[i]) * realPartFFT[i]) - (sin(phi[i]) * imagPartFFT[i]);
5529
shifterImag[i] = (cos(phi[i]) * imagPartFFT[i]) + (sin(phi[i]) * realPartFFT[i]);
5532
/*********************************************************************
5533
* Now deleting the memory allocated for phi[]. *
5534
*********************************************************************/
5537
/*********************************************************************
5538
* Now we need to get the inverse FFT of shifter. Therefore, we need *
5539
* to take the inverse FFT's of shifterReal and shifterImag. Each of *
5540
* these inverse FFT's will have a real part and an imaginary part. *
5542
* For shifterReal, its inverse FFT parts will be stored in *
5543
* shifterRealIFFTReal and shifterRealIFFTImag. For shifterImag, its *
5544
* inverse FFT parts will be stored in shifterImagIFFTReal and *
5545
* shifterImagIFFTImag. *
5546
*********************************************************************/
5547
VB_Vector shifterRealIFFTReal(tSeries.getLength());
5548
VB_Vector shifterRealIFFTImag(tSeries.getLength());
5549
VB_Vector shifterImagIFFTReal(tSeries.getLength());
5550
VB_Vector shifterImagIFFTImag(tSeries.getLength());
5552
/*********************************************************************
5553
* Now computing the inverse FFT's of shifterReal and shifterImag. *
5554
*********************************************************************/
5555
shifterReal.ifft(shifterRealIFFTReal, shifterRealIFFTImag);
5556
shifterImag.ifft(shifterImagIFFTReal, shifterImagIFFTImag);
5558
/*********************************************************************
5559
* Now assigning the real part of the inverse FFT of shifter to *
5561
*********************************************************************/
5562
shiftedSignal = shifterRealIFFTReal - shifterImagIFFTImag;
5564
} // void VB_Vector::phaseShift(const VB_Vector& tSeries,
5565
// const double timeShift, VB_Vector& shiftedSignal)
5567
/*********************************************************************
5568
* This instance method calls the static method *
5569
* VB_Vector::phaseShift() to compute the phase shift, using this *
5570
* instance of VB_Vector as the first argument to the static *
5571
* VB_Vector::phaseShift() method. *
5572
*********************************************************************/
5573
void VB_Vector::phaseShift(const double timeShift,
5574
VB_Vector& shiftedSignal) const
5576
VB_Vector::phaseShift(*this, timeShift, shiftedSignal);
5577
} // void VB_Vector::phaseShift(const double timeShift,
5578
// VB_Vector& shiftedSignal) const
5580
/*********************************************************************
5581
* This instance method calls the static method *
5582
* VB_Vector::phaseShift() to compute the phase shift, using this *
5583
* instance of VB_Vector as the first argument to the static *
5584
* VB_Vector::phaseShift() method. Then the resulting phase shifted *
5585
* VB_Vector is assigned to this instance of VB_Vector. *
5586
*********************************************************************/
5587
void VB_Vector::phaseShift(const double timeShift)
5590
/*********************************************************************
5591
* tempVector will be used to hold the phase shifted vector. *
5592
*********************************************************************/
5593
VB_Vector tempVector = VB_Vector();
5595
/*********************************************************************
5596
* Calling the static method VB_Vector::phaseShift() to carry out the *
5597
* phase shifting. Then tempVector is assigned to this instance of *
5599
*********************************************************************/
5600
VB_Vector::phaseShift(*this, timeShift, tempVector);
5601
(*this) = tempVector;
5603
} // void VB_Vector::phaseShift(const double timeShift)
5605
/*********************************************************************
5606
* phi[] is an array needed to carry out the phase shift. phi[0] *
5607
* will always be zero. The "lower half" values of phi[] will be *
5608
* calculated and the "upper half" values of phi[] depend on its *
5609
* "lower half" values. Specifically, the "lower half" values are *
5610
* computed up to and including phi[length/2]. Then the "lower half" *
5611
* values are reflected about the x-axis, and then about the *
5612
* vertical line y = (length/2). Assume that the x-axis indexes phi[] *
5613
* and the y-axis is phi[i]. If length is 10, the graph of phi[] looks*
5638
* -----o---+---+---+---+---+---+---+---+---+---+ *
5639
* | 1 2 3 4 5 6 7 8 9 *
5656
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5657
* ---------------- ----- ------------ *
5658
* phi double * Array used to hold the result. *
5660
* length int Length of phi[]. *
5662
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5663
* ----------------- ----- ------------ *
5664
* phi double * Holds the results. *
5665
********************************************************************/
5666
void VB_Vector::makePhi(double *phi, const int length, const double timeShift)
5669
/*********************************************************************
5670
* Setting all elements in phi[] to zero. *
5671
*********************************************************************/
5672
memset(phi, 0, sizeof(double) * length);
5674
/*********************************************************************
5675
* halfLength holds the floor of length / 2. *
5676
*********************************************************************/
5677
int halfLength = length / 2;
5679
/*********************************************************************
5680
* Even number of values. *
5681
*********************************************************************/
5682
if ( (length % 2) == 0 )
5685
/*********************************************************************
5686
* Now calculating the values for phi[] (for the case of an even *
5687
* number of values in timeSeries[]. *
5688
*********************************************************************/
5689
for (int j = 1; j <= halfLength; j++)
5692
/*********************************************************************
5693
* The following line calculates the "lower half" values of phi[]. *
5694
*********************************************************************/
5695
phi[j] = -1.0 * (timeShift * TWOPI) / ((double ) length / (double ) j);
5697
/*********************************************************************
5698
* When j is not equal to halfLength, then calculate the "upper half" *
5699
* values of phi[]. *
5700
*********************************************************************/
5701
if (j != halfLength)
5703
phi[length - j] = -1.0 * phi[j];
5710
/*********************************************************************
5711
* Odd number of values. *
5712
*********************************************************************/
5716
/*********************************************************************
5717
* Now calculating the values for phi[] (for the case of an odd *
5718
* number of values in timeSeries[]. *
5719
*********************************************************************/
5720
for (int j = 1; j <= halfLength; j++)
5723
/*********************************************************************
5724
* The following line calculates the "lower half" values of phi[]. *
5725
*********************************************************************/
5726
phi[j] = -1.0 * (timeShift * TWOPI) / ((double ) length / (double ) j);
5728
/*********************************************************************
5729
* The following line calculates the "upper half" values of phi[]. *
5730
*********************************************************************/
5731
phi[length - j] = -1.0 * phi[j];
5737
} // void VB_Vector::makePhi(double *phi, const int length, const double timeShift)
5739
/*********************************************************************
5740
* This private static method computes the sine of a complex number *
5741
* that is in Cartesian form. The real part of the sine is assigned *
5742
* to real. The imaginary part of the sine is assigned to imaginary. *
5744
* Here' how the sine is computed: *
5746
* Let z = x + iy, a complex number. Then *
5748
* sin(z) = (sin(x)) * ((e^y + e^(-y)))/2 + *
5749
* i * (cos(x)) * ((e^y - e^(-y)))/2 *
5751
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5752
* ---------------- ----- ------------ *
5753
* x const double The real part of the complex *
5754
* number whose sine is to be *
5756
* y const double The imaghinary part of the *
5757
* complex number whose sine is to *
5759
* real double& Will hold the real part of the *
5761
* imaginary double& Will hold the imaginary part of *
5764
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5765
* ----------------- ----- ------------ *
5768
* EXCEPTIONS THROWN: *
5769
* ------------------ *
5771
*********************************************************************/
5772
void VB_Vector::complexSin(const double x, const double y, double& real, double& imaginary)
5775
/*********************************************************************
5776
* Now getting the needed exponentials. *
5777
*********************************************************************/
5778
double eToTheY = exp(y);
5779
double eToTheMinusY = exp(-y);
5781
/*********************************************************************
5782
* Now computing and assigning the real and imaginary parts of the *
5784
*********************************************************************/
5785
real = sin(x) * ((eToTheY + eToTheMinusY) / 2.0);
5786
imaginary = cos(x) * ((eToTheY - eToTheMinusY) / 2.0);
5788
} // void VB_Vector::complexSin(const double x, const double y, double& real, double& imaginary)
5790
/*********************************************************************
5791
* This private static method computes the cosine of a complex number *
5792
* that is in Cartesian form. The real part of the cosine is assigned *
5793
* to real. The imaginary part of the cosine is assigned to imaginary.*
5795
* Here' how the cosine is computed: *
5797
* Let z = x + iy, a complex number. Then *
5799
* cos(z) = sin(z + Pi/2) *
5801
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5802
* ---------------- ----- ------------ *
5803
* x const double The real part of the complex *
5804
* number whose cosine is to be *
5806
* y const double The imaghinary part of the *
5807
* complex number whose cosine is *
5809
* real double& Will hold the real part of the *
5811
* imaginary double& Will hold the imaginary part of *
5814
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5815
* ----------------- ----- ------------ *
5818
* EXCEPTIONS THROWN: *
5819
* ------------------ *
5821
*********************************************************************/
5822
void VB_Vector::complexCos(const double x, const double y, double& real, double& imaginary)
5825
/*********************************************************************
5826
* Now computing the cosine. *
5827
*********************************************************************/
5828
VB_Vector::complexSin(x + (PI / 2.0), y, real, imaginary);
5830
} // void VB_Vector::complexCos(const double x, const double y, double& real, double& imaginary)
5833
/*********************************************************************
5834
* This instance method normalizes the magnitude component of a signal*
5835
* to unity while preserving the phase component. This method is a *
5836
* port of the IDL NormMag function, found in VoxBo_Fourier.pro. *
5838
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5839
* ---------------- ----- ------------ *
5840
* this VB_Vector * The input signal. *
5842
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5843
* ----------------- ----- ------------ *
5846
* EXCEPTIONS THROWN: *
5847
* ------------------ *
5849
*********************************************************************/
5850
void VB_Vector::normMag()
5853
/*********************************************************************
5854
* We now need to compute the FFT of this instance of VB_Vector. *
5855
* realFFT will hold the real part of the FFT, while imagIFFT will *
5856
* hold the imaginary part of the FFT. *
5857
*********************************************************************/
5858
VB_Vector realFFT = VB_Vector();
5859
VB_Vector imagIFFT = VB_Vector();
5860
this->fft(realFFT, imagIFFT);
5862
/*********************************************************************
5863
* magImage[] will hold the modulus of each complex number from the *
5864
* FFT of this instance of VB_Vector. *
5865
*********************************************************************/
5866
double *magImage = new double[this->getLength()];
5868
/*********************************************************************
5869
* theZeros is used to hold the indices of where magImage is zero. *
5870
*********************************************************************/
5871
vector<unsigned long> theZeros;
5873
/*********************************************************************
5874
* The following for loop populates magImage. *
5875
*********************************************************************/
5876
for (unsigned long i = 0; i < this->getLength(); i++)
5878
magImage[i] = sqrt((realFFT[i] * realFFT[i]) + (imagIFFT[i] * imagIFFT[i]));
5880
/*********************************************************************
5881
* NOTE: If the modulus is zero, then the phase angle is undefined. *
5882
* To get around this, magImage[i] is set to 1.0, temporarily. Also, *
5883
* the index is added to theZeros. *
5884
*********************************************************************/
5885
if (magImage[i] == 0.0)
5888
theZeros.push_back(i);
5893
/*********************************************************************
5894
* phaseImage[i] will be used to hold the arc-cosine of realFTT[i] *
5895
* divided by magImage[i]. *
5896
*********************************************************************/
5897
double *phaseImage = new double[this->getLength()];
5899
/*********************************************************************
5900
* This for loop populates realFFT[i]. *
5901
*********************************************************************/
5902
for (unsigned long i = 0; i < this->getLength(); i++)
5904
phaseImage[i] = acos(realFFT[i] / magImage[i]);
5906
/*********************************************************************
5907
* Since the domain of acos() is limited, we need to check the sign *
5909
*********************************************************************/
5910
if (imagIFFT[i] < 0.0)
5912
phaseImage[i] = TWOPI - phaseImage[i];
5916
/*********************************************************************
5917
* The following for loop is sued to "restore" the zero values in *
5918
* magImage[] and phaseImage[]. *
5919
*********************************************************************/
5920
for (unsigned long i = 0; i < theZeros.size(); i++)
5923
phaseImage[i] = 0.0;
5926
/*********************************************************************
5927
* magImageMax is assigned the maximum value of magImage[]. *
5928
*********************************************************************/
5929
double magImageMax = getMax(magImage, this->getLength());
5931
/*********************************************************************
5932
* realPart is used to hold the real part of the normalized signal *
5933
* and imagPart is used to hold the imaginary part of the normalized *
5935
*********************************************************************/
5936
VB_Vector realPart(this->getLength());
5937
VB_Vector imagPart(this->getLength());
5939
/*********************************************************************
5940
* The following for loop is used to populate both realPart and *
5942
*********************************************************************/
5943
for (unsigned long i =0; i < this->getLength(); i++)
5945
realPart[i] = (magImage[i] / magImageMax) * cos(phaseImage[i]);
5946
imagPart[i] = (magImage[i] / magImageMax) * sin(phaseImage[i]);
5949
/*********************************************************************
5950
* We now need to convert back to the time domain. realPartFFTReal *
5951
* will be used to hold the real part of the inverse FFT of realPart *
5952
* and realPartFFTImag will be used to hold the imaginary part of the *
5953
* inverse FFT of realPart. *
5954
*********************************************************************/
5955
VB_Vector realPartFFTReal = VB_Vector();
5956
VB_Vector realPartFFTImag = VB_Vector();
5957
realPart.ifft(realPartFFTReal, realPartFFTImag);
5959
/*********************************************************************
5960
* imagPartFFTReal will be used to hold the real part of the inverse *
5961
* FFT of imagPart and imagPartFFTImag will be used to hold the *
5962
* imaginary part of the inverse FFT of imagPart. *
5963
*********************************************************************/
5964
VB_Vector imagPartFFTReal = VB_Vector();
5965
VB_Vector imagPartFFTImag = VB_Vector();
5966
imagPart.ifft(imagPartFFTReal, imagPartFFTImag);
5968
/*********************************************************************
5969
* Now setting this instance of VB_Vector to its normalized form. *
5970
*********************************************************************/
5971
(*this) = realPartFFTReal - imagPartFFTImag;
5973
/*********************************************************************
5974
* Deleting previously allocated memory. *
5975
*********************************************************************/
5976
deleteArrMem(phaseImage);
5977
deleteArrMem(magImage);
5979
} // void VB_Vector::normMag()
5981
/*********************************************************************
5982
* This instance method normalizes the magnitude component of a signal*
5983
* to unity while preserving the phase component. This method is a *
5984
* port of the IDL NormMag function, found in VoxBo_Fourier.pro. *
5986
* INPUT VARIABLES: TYPE: DESCRIPTION: *
5987
* ---------------- ----- ------------ *
5988
* normalizedVec VB_Vector& Will hold the normalized vector.*
5990
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
5991
* ----------------- ----- ------------ *
5994
* EXCEPTIONS THROWN: *
5995
* ------------------ *
5997
*********************************************************************/
5998
void VB_Vector::normMag(VB_Vector& normalizedVec) const
6001
/*********************************************************************
6002
* Setting normalizedVec equal to this instance of VB_Vector and then *
6003
* normalizing normalizedVec. *
6004
*********************************************************************/
6005
normalizedVec = (*this);
6006
normalizedVec.normMag();
6008
} // void VB_Vector::normMag(VB_Vector& normalizedVec) const
6010
/*********************************************************************
6011
* This method applies the input function (actually a function *
6012
* pointer) to each element of this instance of VB_Vector. The *
6013
* input function must take a single double argument and return a *
6014
* double. This method is meant to apply sqrt(), cos(), sin(), etc., *
6015
* to each element. *
6017
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6018
* ---------------- ----- ------------ *
6019
* theFunction double (*) (double) A pointer to a function *
6020
* that takes a single *
6021
* double argument and *
6022
* returns a double. *
6024
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6025
* ----------------- ----- ------------ *
6028
* EXCEPTIONS THROWN: *
6029
* ------------------ *
6031
*********************************************************************/
6032
void VB_Vector::applyFunction(double (*theFunction)(double)) throw()
6035
/*********************************************************************
6036
* The following for loop is used to traverse this instance of *
6037
* VB_Vector and apply the input function to each element. *
6038
*********************************************************************/
6039
for (unsigned long i = 0; i < this->getLength(); i++)
6041
(*this)[i] = (*theFunction)((*this)[i]);
6044
} // void VB_Vector::applyFunction(double (*theFunction)(double)) throw()
6046
/*********************************************************************
6047
* This method applies the input function (actually a function *
6048
* pointer) to each element of this instance of VB_Vector and stores *
6049
* the result in theResult. The input function must take a single *
6050
* double argument and return a double. This method is meant to *
6051
* apply sqrt(), cos(), sin(), etc., to each element. *
6053
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6054
* ---------------- ----- ------------ *
6055
* theFunction double (*) (double) A pointer to a function *
6056
* that takes a single *
6057
* double argument and *
6058
* returns a double. *
6059
* theResult VB_Vector& Will hold the result. *
6061
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6062
* ----------------- ----- ------------ *
6065
* EXCEPTIONS THROWN: *
6066
* ------------------ *
6068
*********************************************************************/
6069
void VB_Vector::applyFunction(double (*theFunction)(double), VB_Vector& theResult) const throw()
6072
/*********************************************************************
6073
* Setting theResult equal to this instance of VB_Vector and then *
6074
* calling VB_Vector::applyFunction(). *
6075
*********************************************************************/
6076
theResult = (*this);
6077
theResult.applyFunction(theFunction);
6079
} // void VB_Vector::applyFunction(double (*theFunction)(double), VB_Vector& theResult) const throw()
6081
/*********************************************************************
6082
* This method applies the input function (actually a function *
6083
* pointer) to each element of this instance of VB_Vector and stores *
6084
* the result in theResult. The input function must take a single *
6085
* double argument and return a double. This method is meant to *
6086
* apply sqrt(), cos(), sin(), etc., to each element. *
6088
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6089
* ---------------- ----- ------------ *
6090
* theFunction double (*) (double) A pointer to a function *
6091
* that takes a single *
6092
* double argument and *
6093
* returns a double. *
6094
* theResult VB_Vector * Will hold the result. *
6096
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6097
* ----------------- ----- ------------ *
6100
* EXCEPTIONS THROWN: *
6101
* ------------------ *
6103
*********************************************************************/
6104
void VB_Vector::applyFunction(double (*theFunction)(double), VB_Vector *theResult) const throw()
6107
/*********************************************************************
6108
* Setting theResult equal to this instance of VB_Vector and then *
6109
* calling VB_Vector::applyFunction(). *
6110
*********************************************************************/
6111
(*theResult) = (*this);
6112
theResult->applyFunction(theFunction);
6114
} // void VB_Vector::applyFunction(double (*theFunction)(double), VB_Vector *theResult) const throw()
6116
/*********************************************************************
6117
* This method carries out an element-by-element multiplication *
6118
* between this instance of VB_Vector and the input VB_Vector. This *
6119
* instance of VB_Vector is overwritten with the new values. *
6121
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6122
* ---------------- ----- ------------ *
6123
* vec const VB_Vector * The input vector. *
6125
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6126
* ----------------- ----- ------------ *
6129
* EXCEPTIONS THROWN: *
6130
* ------------------ *
6132
*********************************************************************/
6133
void VB_Vector::elementByElementMult(const VB_Vector *vec) throw()
6136
/*********************************************************************
6137
* The following try/catch blocks are used to ensure that the vector *
6138
* lengths are equal. *
6139
*********************************************************************/
6142
VB_Vector::checkVectorLengths(this->theVector, vec->theVector, __LINE__, __FILE__, __FUNCTION__);
6144
catch (GenericExcep &e)
6146
e.whatNoExit(__LINE__, __FILE__, __FUNCTION__);
6149
/*********************************************************************
6150
* The following for loop carries out the element-by-element *
6152
*********************************************************************/
6153
for (unsigned long i = 0; i < this->getLength(); i++)
6155
(*this)[i] *= (*vec)[i];
6158
} // void VB_Vector::elementByElementMult(const VB_Vector *vec) throw()
6160
/*********************************************************************
6161
* This method carries out an element-by-element multiplication *
6162
* between this instance of VB_Vector and the input VB_Vector. This *
6163
* instance of VB_Vector is overwritten with the new values. *
6165
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6166
* ---------------- ----- ------------ *
6167
* vec const VB_Vector& The input vector. *
6169
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6170
* ----------------- ----- ------------ *
6173
* EXCEPTIONS THROWN: *
6174
* ------------------ *
6176
*********************************************************************/
6177
void VB_Vector::elementByElementMult(const VB_Vector& vec) throw()
6180
/*********************************************************************
6181
* Calling VB_Vector::elementByElementMult(const VB_Vector *vec) to *
6182
* carry out the element-by-element multiplication. *
6183
*********************************************************************/
6184
this->elementByElementMult(&vec);
6186
} // void VB_Vector::elementByElementMult(const VB_Vector& vec) throw()
6188
/*********************************************************************
6189
* This static method multiplies 2 "complex" VB_Vectors: the first *
6190
* complex VB_Vector has its real and imaginary parts passed in; *
6191
* similarly for the second VB_Vector. The real part of the product *
6192
* will be saved to realProd and the imaginary part will be saved to *
6195
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6196
* ---------------- ----- ------------ *
6197
* real1 const VB_Vector& The real part of the first *
6199
* imag1 const VB_Vector& The imaginary part of the *
6200
* first VB_Vector. *
6201
* real2 const VB_Vector& The real part of the second *
6203
* imag2 const VB_Vector& The imaginary part of the *
6204
* second VB_Vector. *
6205
* realProd VB_Vector& Will hold the real part of *
6207
* imagProd VB_Vector& Will hold the imaginary part *
6210
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6211
* ----------------- ----- ------------ *
6214
* EXCEPTIONS THROWN: *
6215
* ------------------ *
6217
*********************************************************************/
6218
void VB_Vector::compMult(const VB_Vector& real1, const VB_Vector& imag1,
6219
const VB_Vector& real2, const VB_Vector& imag2, VB_Vector& realProd,
6220
VB_Vector& imagProd) throw (GenericExcep)
6223
/*********************************************************************
6224
* First, we need to ensure that all the vector lengths are equal. If *
6225
* any of the sizes do not match, then a GenericExcep is thrown. *
6226
*********************************************************************/
6227
VB_Vector::checkVectorLengths(real1.theVector, imag1.theVector, __LINE__, __FILE__, __FUNCTION__);
6228
VB_Vector::checkVectorLengths(real2.theVector, imag2.theVector, __LINE__, __FILE__, __FUNCTION__);
6229
VB_Vector::checkVectorLengths(real1.theVector, imag2.theVector, __LINE__, __FILE__, __FUNCTION__);
6231
/*********************************************************************
6232
* Ensuring that realProd and imagProd are appropriately sized. *
6233
*********************************************************************/
6234
if (real1.getLength() != realProd.getLength())
6236
realProd.resize(real1.theVector->size);
6238
if (real1.getLength() != imagProd.getLength())
6240
imagProd.resize(real1.theVector->size);
6243
/*********************************************************************
6244
* The following for loop carries out the complex multiplication. The *
6245
* real part of the product is saved to realProd, while the imaginary *
6246
* part is saved to imagProd. *
6247
*********************************************************************/
6248
for (unsigned long i = 0; i < real1.theVector->size; i++)
6250
realProd.theVector->data[i] = (real1.theVector->data[i] * real2.theVector->data[i]) - (imag1.theVector->data[i] * imag2.theVector->data[i]);
6251
imagProd.theVector->data[i] = (real1.theVector->data[i] * imag2.theVector->data[i]) + (imag1.theVector->data[i] * real2.theVector->data[i]);
6254
} // void VB_Vector::compMult(const VB_Vector& real1, const VB_Vector& imag1,
6255
// const VB_Vector& real2, const VB_Vector& imag2, VB_Vector& realProd,
6256
// VB_Vector& imagProd) throw (GenericExcep)
6258
/*********************************************************************
6259
* This static method computes the FFT of a "complex" VB_Vector. The *
6260
* real part of the VB_Vector is passed in as real and the imaginary *
6261
* part of the VB_Vector is passed in as imag. The real part of the *
6262
* FFT is saved in realFFT while the imaginary part is saved to *
6265
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6266
* ---------------- ----- ------------ *
6267
* real const VB_Vector& The real part of the input *
6269
* imag const VB_Vector& The imaginary part of the *
6270
* input VB_Vector. *
6271
* realFFT VB_Vector& Will hold the real part *
6273
* imagIFFT VB_Vector& Will hold the imaginary part *
6276
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6277
* ----------------- ----- ------------ *
6280
* EXCEPTIONS THROWN: *
6281
* ------------------ *
6283
*********************************************************************/
6284
void VB_Vector::complexFFT(const VB_Vector& real,
6285
const VB_Vector& imag, VB_Vector& realFFT, VB_Vector& imagIFFT)
6286
throw (GenericExcep)
6289
/*********************************************************************
6290
* Ensuring that the input VB_Vectors real and imag have the same *
6291
* size. If they don't have the same size, then a GenericExcep is *
6293
*********************************************************************/
6294
VB_Vector::checkVectorLengths(real.theVector, imag.theVector, __LINE__, __FILE__, __FUNCTION__);
6296
/*********************************************************************
6297
* Ensuring that realFFT and imagIFFT are sized appropriately. *
6298
*********************************************************************/
6299
if (real.getLength() != realFFT.getLength())
6301
realFFT.resize(real.theVector->size);
6303
if (real.getLength() != imagIFFT.getLength())
6305
imagIFFT.resize(real.theVector->size);
6308
/*********************************************************************
6309
* realFFTreal and realFFTimag will hold the real and imaginary parts *
6310
* of the FFT of real, respectively. *
6311
*********************************************************************/
6312
VB_Vector realFFTreal(real.getLength());
6313
VB_Vector realFFTimag(real.getLength());
6315
/*********************************************************************
6316
* imagIFFTreal and imagIFFTimag will hold the real and imaginary *
6317
* parts of the FFT of imag, respectively. *
6318
*********************************************************************/
6319
VB_Vector imagIFFTreal(real.getLength());
6320
VB_Vector imagIFFTimag(real.getLength());
6322
/*********************************************************************
6323
* Getting the FFT of real. *
6324
*********************************************************************/
6325
real.fft(realFFTreal, realFFTimag);
6327
/*********************************************************************
6328
* Getting the FFT of imag. *
6329
*********************************************************************/
6330
imag.fft(imagIFFTreal, imagIFFTimag);
6332
/*********************************************************************
6333
* Now realFFT will hold the real part of the FFT of *
6334
* (real + i * imag). *
6335
*********************************************************************/
6336
realFFT = realFFTreal - imagIFFTimag;
6338
/*********************************************************************
6339
* Now imagIFFT will hold the imaginary part of the FFT of *
6340
* (real + i * imag). *
6341
*********************************************************************/
6342
imagIFFT = realFFTimag + imagIFFTreal;
6344
} // void VB_Vector::complexFFT(const VB_Vector& real,
6345
// const VB_Vector& imag, VB_Vector& realFFT, VB_Vector& imagIFFT)
6346
// throw (GenericExcep)
6348
/*********************************************************************
6349
* This static method computes the inverse FFT of a "complex" *
6350
* VB_Vector. The real part of the VB_Vector is passed in as real and *
6351
* the imaginary part of the VB_Vector is passed in as imag. The *
6352
* real part of the inverse FFT is saved in realIFFT while the *
6353
* imaginary part is saved to imagIFFT. *
6355
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6356
* ---------------- ----- ------------ *
6357
* real const VB_Vector& The real part of the input *
6359
* imag const VB_Vector& The imaginary part of the *
6360
* input VB_Vector. *
6361
* realIFFT VB_Vector& Will hold the real part *
6362
* of the inverse FFT. *
6363
* imagIFFT VB_Vector& Will hold the imaginary part *
6364
* of the inverse FFT. *
6366
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6367
* ----------------- ----- ------------ *
6370
* EXCEPTIONS THROWN: *
6371
* ------------------ *
6373
*********************************************************************/
6374
void VB_Vector::complexIFFT(const VB_Vector& real,
6375
const VB_Vector& imag, VB_Vector& realIFFT, VB_Vector& imagIFFT)
6376
throw (GenericExcep)
6379
/*********************************************************************
6380
* Ensuring that the input VB_Vectors real and imag have the same *
6381
* size. If they don't have the same size, then a GenericExcep is *
6383
*********************************************************************/
6384
VB_Vector::checkVectorLengths(real.theVector, imag.theVector, __LINE__, __FILE__, __FUNCTION__);
6386
/*********************************************************************
6387
* Ensuring that realIFFT and imagIFFT are sized appropriately. *
6388
*********************************************************************/
6389
if (real.getLength() != realIFFT.getLength())
6391
realIFFT.resize(real.theVector->size);
6393
if (real.getLength() != imagIFFT.getLength())
6395
imagIFFT.resize(real.theVector->size);
6398
/*********************************************************************
6399
* realIFFTreal and realIFFTimag will hold the real and imaginary *
6400
* parts of the inverse FFT of real, respectively. *
6401
*********************************************************************/
6402
VB_Vector realIFFTreal(real.getLength());
6403
VB_Vector realIFFTimag(real.getLength());
6405
/*********************************************************************
6406
* imagIFFTreal and imagIFFTimag will hold the real and imaginary *
6407
* parts of the inverse FFT of imag, respectively. *
6408
*********************************************************************/
6409
VB_Vector imagIFFTreal(real.getLength());
6410
VB_Vector imagIFFTimag(real.getLength());
6412
/*********************************************************************
6413
* Getting the inverse FFT of real. *
6414
*********************************************************************/
6415
real.ifft(realIFFTreal, realIFFTimag);
6417
/*********************************************************************
6418
* Getting the inverse FFT of imag. *
6419
*********************************************************************/
6420
imag.ifft(imagIFFTreal, imagIFFTimag);
6422
/*********************************************************************
6423
* Now realIFFT will hold the real part of the inverse FFT of *
6424
* (real + i * imag). *
6425
*********************************************************************/
6426
realIFFT = realIFFTreal - imagIFFTimag;
6428
/*********************************************************************
6429
* Now imagIFFT will hold the imaginary part of the inverse FFT of *
6430
* (real + i * imag). *
6431
*********************************************************************/
6432
imagIFFT = realIFFTimag + imagIFFTreal;
6434
} // void VB_Vector::complexIFFT(const VB_Vector& real,
6435
// const VB_Vector& imag, VB_Vector& realIFFT, VB_Vector& imagIFFT)
6436
// throw (GenericExcep)
6438
/*********************************************************************
6439
* This static method computes the inverse FFT of a "complex" *
6440
* VB_Vector. The real part of the VB_Vector is passed in as real and *
6441
* the imaginary part of the VB_Vector is passed in as imag. The *
6442
* real part of the inverse FFT is saved in realIFFT while the *
6443
* imaginary part is not saved. *
6445
* INPUT VARIABLES: TYPE: DESCRIPTION: *
6446
* ---------------- ----- ------------ *
6447
* real const VB_Vector& The real part of the input *
6449
* imag const VB_Vector& The imaginary part of the *
6450
* input VB_Vector. *
6451
* realIFFT VB_Vector& Will hold the real part *
6452
* of the inverse FFT. *
6454
* OUTPUT VARIABLES: TYPE: DESCRIPTION: *
6455
* ----------------- ----- ------------ *
6458
* EXCEPTIONS THROWN: *
6459
* ------------------ *
6461
*********************************************************************/
6462
void VB_Vector::complexIFFTReal(const VB_Vector& real,
6463
const VB_Vector& imag, VB_Vector& realIFFT) throw (GenericExcep)
6466
/*********************************************************************
6467
* Ensuring that the input VB_Vectors real and imag have the same *
6468
* size. If they don't have the same size, then a GenericExcep is *
6470
*********************************************************************/
6471
VB_Vector::checkVectorLengths(real.theVector, imag.theVector, __LINE__, __FILE__, __FUNCTION__);
6473
/*********************************************************************
6474
* Ensuring that realIFFT is sized appropriately. *
6475
*********************************************************************/
6476
if (real.getLength() != realIFFT.getLength())
6478
realIFFT.resize(real.theVector->size);
6481
/*********************************************************************
6482
* realIFFTreal and realIFFTimag will hold the real and imaginary *
6483
* parts of the inverse FFT of real, respectively. *
6484
*********************************************************************/
6485
VB_Vector realIFFTreal(real.getLength());
6486
VB_Vector realIFFTimag(real.getLength());
6488
/*********************************************************************
6489
* imagIFFTreal and imagIFFTimag will hold the real and imaginary *
6490
* parts of the inverse FFT of imag, respectively. *
6491
*********************************************************************/
6492
VB_Vector imagIFFTreal(real.getLength());
6493
VB_Vector imagIFFTimag(real.getLength());
6495
/*********************************************************************
6496
* Getting the inverse FFT of real. *
6497
*********************************************************************/
6498
real.ifft(realIFFTreal, realIFFTimag);
6500
/*********************************************************************
6501
* Getting the inverse FFT of imag. *
6502
*********************************************************************/
6503
imag.ifft(imagIFFTreal, imagIFFTimag);
6505
/*********************************************************************
6506
* Now realIFFT will hold the real part of the inverse FFT of *
6507
* (real + i * imag). *
6508
*********************************************************************/
6509
realIFFT = realIFFTreal - imagIFFTimag;
6511
} // void VB_Vector::complexIFFTReal(const VB_Vector& real,
6512
// const VB_Vector& imag, VB_Vector& realIFFT) throw (GenericExcep)
6516
VB_Vector::meanNormalize()
6518
double avg=this->getVectorMean();
6519
if (fabs(avg) < 1.0) {
6524
else if (avg >= 0.0) {
6534
VB_Vector::removeDrift()
6536
double intercept = 0.0, slope = 0.0, cov00 = 0.0, cov01 = 0.0, cov11 = 0.0, chisq = 0.0;
6537
int size = getLength();
6539
double x[size], y[size], w[size];
6540
for (int i = 0; i < size; i++) {
6542
y[i] = getElement(i);
6545
gsl_fit_wlinear(x,1,w,1,y,1,size,&intercept,&slope,&cov00,&cov01,&cov11,&chisq);
6546
mean = getVectorMean();
6547
for (int index = 0; index < size; index++)
6548
setElement(index,(getElement(index)-(intercept + slope*index)) + mean);
6552
double* VB_Vector::begin() const
6554
if (this->theVector)
6555
return this->theVector->data;
6559
double* VB_Vector::end() const
6561
if (this->theVector)
6562
return this->theVector->data + this->theVector->size;
6564
} // double* VB_Vector::end() const
6566
// FIXME : DYK : added the following functions to handle the new i/o system
6569
VB_Vector::ReadFile(const string &fname)
6573
if ((err=iovec.ReadFile(fname)))
6575
fileFormat=iovec.fileformat;
6577
memcpy(this->theVector->data, iovec.data, sizeof(double) * this->getLength());
6582
VB_Vector::WriteFile()
6586
iovec.resize(getLength());
6587
memcpy(iovec.data, this->theVector->data, sizeof(double) * this->getLength());
6588
iovec.fileformat=fileFormat;
6589
iovec.SetFileName(fileName);
6590
err=iovec.WriteFile();
6595
VB_Vector::WriteFile(const string &fname)
6601
// DYK: added the following non-member function to do a t-test
6604
ttest(const VB_Vector &v1,const VB_Vector &v2)
6606
double s1=v1.getVariance();
6607
double s2=v2.getVariance();
6608
double mean1=v1.getVectorMean();
6609
double mean2=v2.getVectorMean();
6611
(mean1-mean2)/sqrt((s1/v1.getLength())+(s2/v2.getLength()));
6614
// DYK: added the following non-member function to calculate power
6618
fftnyquist(VB_Vector &vv)
6620
int len=vv.getLength();
6621
VB_Vector fullFFT(len);
6625
VB_Vector halfFFT(newlen);
6627
for (int i=0; i<newlen; i++) {
6628
halfFFT.setElement(i,fullFFT.getElement(i));
6634
// DYK: added to the following better-behaved function for resampling
6638
cspline_resize(VB_Vector vec,double factor)
6640
int newsize=(int)((float)vec.size()*factor);
6641
VB_Vector bogus(vec.size());
6642
for (int i=0; i<vec.size(); i++)
6643
bogus.setElement(i,i);
6644
VB_Vector newvector(newsize);
6645
double interval=1.0/factor;
6647
double *xptr=bogus.getTheVector()->data;
6648
double *yptr=vec.getTheVector()->data;
6649
gsl_interp *myinterp=gsl_interp_alloc(gsl_interp_cspline,vec.size());
6650
// gsl_interp *myinterp=gsl_interp_alloc(gsl_interp_linear,vec.size());
6651
gsl_interp_init(myinterp,xptr,yptr,vec.size());
6653
for (int i=0; i<newsize; i++) {
6654
val=gsl_interp_eval(myinterp,xptr,yptr,pos,NULL);
6655
newvector.setElement(i,val);
6658
gsl_interp_free(myinterp);
6662
// DYK: added the following useful functions
6665
correlation(const VB_Vector &v1,const VB_Vector &v2)
6667
if (v1.size()!=v2.size())
6669
double sd1=sqrt(v1.getVariance());
6670
double sd2=sqrt(v2.getVariance());
6671
return (covariance(v1,v2)/(sd1*sd2));
6675
covariance(const VB_Vector &v1,const VB_Vector &v2)
6677
if (v1.size()!=v2.size())
6679
return gsl_stats_covariance(v1.getTheVector()->data,1,
6680
v2.getTheVector()->data,1,
6684
// DYK: frequency domain filtering. dfftfilter_frequencies lets you
6685
// specify the frequencies you'd like to remove in Hz
6689
// dfftfilter_frequencies(VB_Vector &signal,VB_Vector filtermask,
6690
// double samplingrate,double low,double high)
6692
// int nfreq=signal.getLength()/2;
6694
// if (signal.getLength()<4)
6696
// VB_Vector sig_real(signal.getLength());
6697
// VB_Vector sig_imag(signal.getLength());
6698
// signal.fft(sig_real,sig_imag);
6702
// sig_real.print();
6703
// // sig_imag.print();
6704
// //for (int i=0; i<signal.getLength(); i++)
6705
// //printf("freq %d is %.3f\n",i,(double)i/(signal.getLength()*samplingrate));
6707
// for (int i=1; i<2; i++) {
6709
// sig_real(16-(i+1))=0.0;
6711
// sig_real.print();
6714
// VB_Vector::complexIFFTReal(sig_real,sig_imag,signal);
6716
// return 0; // no error!
6720
VB_Vector::permute(const VB_Vector &v)
6722
if (size()!=v.size())
6724
VB_Vector tmp(size());
6725
for (int i=0; i<size(); i++)
6726
tmp[i]=getElement((int)v[i]);
6727
for (int i=0; i<size(); i++)
6728
setElement(i,tmp[i]);
6733
VB_Vector::permute(VBMatrix &m,int col)