From 1afa7cdce0e7c478925446426a055f62c557157e Mon Sep 17 00:00:00 2001 From: ajturner Date: Mon, 29 Dec 2014 22:53:25 -0500 Subject: [PATCH] :rocket: import from SourceForge --- CVS/Entries | 10 + CVS/Repository | 1 + CVS/Root | 1 + INSTALL | 10 + Jamfile | 28 + Jamrules | 78 + LICENSE | 340 ++++ Makefile | 55 + README | 22 + VERSION | 1 + doc/About.h | 8 + doc/CVS/Entries | 13 + doc/CVS/Repository | 1 + doc/CVS/Root | 1 + doc/CodingStandards.h | 101 ++ doc/CommentStandards.h | 102 ++ doc/Intallation.h | 49 + doc/Introduction.h | 91 + doc/License.h | 415 +++++ doc/Mainpage.h | 20 + doc/Makefile | 54 + doc/Tutorials.h | 373 ++++ doc/UsingFramework.h | 52 + doc/doxyMatrix | 969 ++++++++++ doc/doxyfile | 971 +++++++++++ doc/html/AstroToolbox_8h-source.html | 103 ++ doc/html/AstroToolbox_8h.html | 222 +++ doc/html/Attitude_8h-source.html | 79 + doc/html/Attitude_8h.html | 88 + doc/html/CVS/Entries | 123 ++ doc/html/CVS/Repository | 1 + doc/html/CVS/Root | 1 + doc/html/Environment_8cpp.html | 18 + doc/html/Environment_8h-source.html | 91 + doc/html/Environment_8h.html | 359 ++++ doc/html/Matrix_8cpp.html | 18 + doc/html/Matrix_8h-source.html | 93 + doc/html/Matrix_8h.html | 444 +++++ doc/html/Orbit_8cpp.html | 19 + doc/html/Orbit_8h-source.html | 78 + doc/html/Orbit_8h.html | 38 + doc/html/Plot_8h-source.html | 37 + doc/html/Plot_8h.html | 64 + doc/html/RigidBody_8cpp.html | 64 + doc/html/RigidBody_8h-source.html | 57 + doc/html/RigidBody_8h.html | 36 + doc/html/Rotation_8cpp.html | 36 + doc/html/Rotation_8h-source.html | 276 +++ doc/html/Rotation_8h.html | 115 ++ doc/html/RungeKutta_8h-source.html | 68 + doc/html/RungeKutta_8h.html | 121 ++ doc/html/SpacecraftTime_8h-source.html | 46 + doc/html/SpacecraftTime_8h.html | 21 + .../SpacecraftToolboxConstants_8h-source.html | 27 + doc/html/SpacecraftToolboxConstants_8h.html | 128 ++ doc/html/Spacecraft_8cpp.html | 18 + doc/html/Spacecraft_8h-source.html | 126 ++ doc/html/Spacecraft_8h.html | 113 ++ doc/html/Spacecraft__Sim_8cpp.html | 155 ++ doc/html/TestRotation_8cpp.html | 76 + doc/html/Trigonometry_8h-source.html | 63 + doc/html/Trigonometry_8h.html | 43 + doc/html/annotated.html | 26 + doc/html/bug.html | 25 + doc/html/classAttitude-members.html | 23 + doc/html/classAttitude.html | 333 ++++ doc/html/classCEnvironment-members.html | 29 + doc/html/classCEnvironment.html | 444 +++++ .../classDirectionCosineMatrix-members.html | 38 + doc/html/classDirectionCosineMatrix.html | 907 ++++++++++ doc/html/classEnvironment-members.html | 29 + doc/html/classEnvironment.html | 447 +++++ doc/html/classMatrix-members.html | 16 + doc/html/classMatrix.html | 52 + ...ssModifiedRodriguezParameters-members.html | 40 + .../classModifiedRodriguezParameters.html | 927 ++++++++++ doc/html/classOrbit-members.html | 28 + doc/html/classOrbit.html | 257 +++ doc/html/classQuaternion-members.html | 36 + doc/html/classQuaternion.html | 849 +++++++++ doc/html/classRigidBody-members.html | 21 + doc/html/classRigidBody.html | 254 +++ doc/html/classRotation-members.html | 40 + doc/html/classRotation.html | 960 ++++++++++ doc/html/classSpacecraft-members.html | 35 + doc/html/classSpacecraft.html | 50 + doc/html/classZeit-members.html | 21 + doc/html/classZeit.html | 203 +++ doc/html/doxygen.css | 49 + doc/html/doxygen.png | Bin 0 -> 2352 bytes doc/html/files.html | 37 + doc/html/form_0.png | Bin 0 -> 642 bytes doc/html/form_1.png | Bin 0 -> 559 bytes doc/html/form_10.png | Bin 0 -> 1018 bytes doc/html/form_11.png | Bin 0 -> 1035 bytes doc/html/form_12.png | Bin 0 -> 999 bytes doc/html/form_13.png | Bin 0 -> 185 bytes doc/html/form_14.png | Bin 0 -> 195 bytes doc/html/form_15.png | Bin 0 -> 207 bytes doc/html/form_16.png | Bin 0 -> 386 bytes doc/html/form_17.png | Bin 0 -> 345 bytes doc/html/form_18.png | Bin 0 -> 336 bytes doc/html/form_19.png | Bin 0 -> 908 bytes doc/html/form_2.png | Bin 0 -> 194 bytes doc/html/form_20.png | Bin 0 -> 403 bytes doc/html/form_21.png | Bin 0 -> 328 bytes doc/html/form_3.png | Bin 0 -> 201 bytes doc/html/form_4.png | Bin 0 -> 1759 bytes doc/html/form_5.png | Bin 0 -> 1814 bytes doc/html/form_6.png | Bin 0 -> 3206 bytes doc/html/form_7.png | Bin 0 -> 3464 bytes doc/html/form_8.png | Bin 0 -> 2823 bytes doc/html/form_9.png | Bin 0 -> 908 bytes doc/html/formula.repository | 22 + doc/html/functions.html | 141 ++ doc/html/globals.html | 130 ++ doc/html/group__Attitude.html | 362 ++++ doc/html/group__AttitudeControl.html | 118 ++ doc/html/group__AttitudeRepresentation.html | 23 + doc/html/group__Constructors.html | 151 ++ doc/html/group__DCM.html | 23 + doc/html/group__DCMOperators.html | 90 + doc/html/group__DirectionCosineMatrix.html | 130 ++ doc/html/group__EOM.html | 188 ++ doc/html/group__FileAccess.html | 180 ++ doc/html/group__History.html | 225 +++ doc/html/group__MRP.html | 23 + doc/html/group__MRPOperators.html | 90 + .../group__ModifiedRodriguezParameters.html | 86 + doc/html/group__Orbital.html | 191 ++ doc/html/group__OrbitalControl.html | 58 + doc/html/group__Physical.html | 118 ++ doc/html/group__Propagators.html | 78 + doc/html/group__Quaternion.html | 26 + doc/html/group__QuaternionOperators.html | 90 + doc/html/group__Rotation.html | 23 + doc/html/group__RotationInspectors.html | 176 ++ doc/html/group__RotationMutators.html | 252 +++ doc/html/group__RotationOperators.html | 151 ++ doc/html/group__SpacecraftFramework.html | 29 + doc/html/group__Trigonometry.html | 406 +++++ doc/html/group__Zeit.html | 20 + doc/html/index.html | 39 + doc/html/main_8cpp.html | 54 + doc/html/modules.html | 36 + doc/html/namespaces.html | 18 + doc/html/namespacestd.html | 19 + doc/html/namespacetechsoft.html | 19 + doc/html/pages.html | 20 + doc/html/todo.html | 183 ++ packages/CVS/Entries | 3 + packages/CVS/Repository | 1 + packages/CVS/Root | 1 + packages/matrixLib.tar.gz | Bin 0 -> 47221 bytes packages/rotationLib.tar.gz | Bin 0 -> 51903 bytes src/CVS/Entries | 13 + src/CVS/Repository | 1 + src/CVS/Root | 1 + src/Jamfile | 37 + src/Makefile | 79 + src/SampleFile.cpp | 35 + src/attitude/Attitude.cpp | 176 ++ src/attitude/Attitude.h | 259 +++ src/attitude/AttitudeModels/CVS/Entries | 2 + src/attitude/AttitudeModels/CVS/Repository | 1 + src/attitude/AttitudeModels/CVS/Root | 1 + .../AttitudeModels/QuaternionAngVelDynamics.h | 136 ++ src/attitude/AttitudeState.cpp | 122 ++ src/attitude/AttitudeState.h | 167 ++ src/attitude/CVS/Entries | 8 + src/attitude/CVS/Repository | 1 + src/attitude/CVS/Root | 1 + src/attitude/Jamfile | 29 + src/attitude/Makefile | 184 ++ src/attitude/attitude.pro | 25 + src/datahandling/AttitudeHistory.cpp | 214 +++ src/datahandling/AttitudeHistory.h | 214 +++ src/datahandling/CVS/Entries | 10 + src/datahandling/CVS/Repository | 1 + src/datahandling/CVS/Root | 1 + src/datahandling/History.cpp | 201 +++ src/datahandling/History.h | 193 ++ src/datahandling/Jamfile | 30 + src/datahandling/Makefile | 180 ++ src/datahandling/OrbitHistory.cpp | 169 ++ src/datahandling/OrbitHistory.h | 162 ++ src/datahandling/datahandling.pro | 27 + src/dynamics/AnalyticPropagator.h | 60 + src/dynamics/CVS/Entries | 11 + src/dynamics/CVS/Repository | 1 + src/dynamics/CVS/Root | 1 + src/dynamics/CombinedNumericPropagator.cpp | 166 ++ src/dynamics/CombinedNumericPropagator.h | 98 ++ src/dynamics/Jamfile | 30 + src/dynamics/NumericPropagator.cpp | 57 + src/dynamics/NumericPropagator.h | 81 + src/dynamics/Propagator.cpp | 75 + src/dynamics/Propagator.h | 168 ++ src/dynamics/QuaternionDynamics.h | 41 + src/dynamics/dynamics.pro | 27 + src/environment/CVS/Entries | 7 + src/environment/CVS/Repository | 1 + src/environment/CVS/Root | 1 + src/environment/CentralBody/CVS/Entries | 5 + src/environment/CentralBody/CVS/Repository | 1 + src/environment/CentralBody/CVS/Root | 1 + src/environment/CentralBody/CentralBody.cpp | 72 + src/environment/CentralBody/CentralBody.h | 132 ++ .../CentralBody/EarthCentralBody.cpp | 63 + .../CentralBody/EarthCentralBody.h | 54 + .../CentralBody/Models/CVS/Entries | 4 + .../CentralBody/Models/CVS/Repository | 1 + src/environment/CentralBody/Models/CVS/Root | 1 + .../CentralBody/Models/MagneticModel.h | 70 + .../Models/TiltedDipoleMagneticModel.cpp | 49 + .../Models/TiltedDipoleMagneticModel.h | 47 + src/environment/Disturbances/CVS/Entries | 4 + src/environment/Disturbances/CVS/Repository | 1 + src/environment/Disturbances/CVS/Root | 1 + .../Disturbances/GravityFunctions.h | 129 ++ .../Disturbances/SolarDisturbances.h | 100 ++ .../Disturbances/ThirdBodyDisturbances.h | 68 + src/environment/Environment.cpp | 260 +++ src/environment/Environment.h | 272 +++ src/environment/Jamfile | 29 + src/environment/Makefile | 232 +++ src/environment/environment.pro | 34 + src/kinematics/CVS/Entries | 2 + src/kinematics/CVS/Repository | 1 + src/kinematics/CVS/Root | 1 + src/kinematics/QuaternionKinematics.h | 37 + src/matrix/CVS/Entries | 55 + src/matrix/CVS/Repository | 1 + src/matrix/CVS/Root | 1 + src/matrix/Jamfile | 46 + src/matrix/Makefile | 584 +++++++ src/matrix/Matrix.h | 133 ++ src/matrix/access.h | 31 + src/matrix/arraybse.cpp | 1529 ++++++++++++++++ src/matrix/arraybse.h | 205 +++ src/matrix/arraygph.cpp | 530 ++++++ src/matrix/arrayops.cpp | 39 + src/matrix/arrayutl.cpp | 181 ++ src/matrix/bnengine.h | 84 + src/matrix/camblas/CVS/Entries | 29 + src/matrix/camblas/CVS/Repository | 1 + src/matrix/camblas/CVS/Root | 1 + src/matrix/camblas/Jamfile | 15 + src/matrix/camblas/blas.cpp | 138 ++ src/matrix/camblas/blas.h | 42 + src/matrix/camblas/blasimpexp.h | 35 + src/matrix/camblas/cblasimpexp.h | 6 + src/matrix/camblas/cinterface.pdf | Bin 0 -> 239226 bytes src/matrix/camblas/dasum.c | 84 + src/matrix/camblas/daxpy.c | 93 + src/matrix/camblas/dcopy.c | 93 + src/matrix/camblas/ddot.c | 95 + src/matrix/camblas/dgemm.c | 452 +++++ src/matrix/camblas/dgemv.c | 375 ++++ src/matrix/camblas/dger.c | 197 +++ src/matrix/camblas/dnrm2.c | 213 +++ src/matrix/camblas/drot.c | 128 ++ src/matrix/camblas/dscal.c | 79 + src/matrix/camblas/dswap.c | 101 ++ src/matrix/camblas/dsymv.c | 301 ++++ src/matrix/camblas/dsyr2.c | 265 +++ src/matrix/camblas/dsyr2k.c | 421 +++++ src/matrix/camblas/dtrmm.c | 480 +++++ src/matrix/camblas/dtrmv.c | 360 ++++ src/matrix/camblas/f2c.h | 214 +++ src/matrix/camblas/ilaenv.c | 573 ++++++ src/matrix/camblas/lsame.c | 116 ++ src/matrix/camblas/s_cmp.c | 44 + src/matrix/camblas/s_copy.c | 27 + src/matrix/camblas/xerbla.c | 55 + src/matrix/camlapack/CVS/Entries | 31 + src/matrix/camlapack/CVS/Repository | 1 + src/matrix/camlapack/CVS/Root | 1 + src/matrix/camlapack/Jamfile | 12 + src/matrix/camlapack/camlaimpexp.h | 6 + src/matrix/camlapack/d_lg10.c | 15 + src/matrix/camlapack/d_sign.c | 12 + src/matrix/camlapack/dgecon.c | 225 +++ src/matrix/camlapack/dgeequ.c | 295 ++++ src/matrix/camlapack/dgerfs.c | 426 +++++ src/matrix/camlapack/dgesvx.c | 564 ++++++ src/matrix/camlapack/dgetf2.c | 174 ++ src/matrix/camlapack/dgetrf.c | 213 +++ src/matrix/camlapack/dgetrs.c | 183 ++ src/matrix/camlapack/dlabad.c | 72 + src/matrix/camlapack/dlacon.c | 256 +++ src/matrix/camlapack/dlacpy.c | 127 ++ src/matrix/camlapack/dlamch.c | 1046 +++++++++++ src/matrix/camlapack/dlange.c | 204 +++ src/matrix/camlapack/dlaqge.c | 191 ++ src/matrix/camlapack/dlassq.c | 116 ++ src/matrix/camlapack/dlaswp.c | 134 ++ src/matrix/camlapack/dlatrs.c | 869 +++++++++ src/matrix/camlapack/drscl.c | 135 ++ src/matrix/camlapack/dtrsm.c | 510 ++++++ src/matrix/camlapack/dtrsv.c | 357 ++++ src/matrix/camlapack/f2c.h | 214 +++ src/matrix/camlapack/i_dnnt.c | 14 + src/matrix/camlapack/idamax.c | 77 + src/matrix/camlapack/ilaenv.c | 572 ++++++ src/matrix/camlapack/pow_di.c | 34 + src/matrix/camlapack/s_cmp.c | 44 + src/matrix/camlapack/s_copy.c | 27 + src/matrix/cammva.h | 5 + src/matrix/camtype.h | 72 + src/matrix/darray.cpp | 1 + src/matrix/darray.h | 523 ++++++ src/matrix/datahndl.cpp | 478 +++++ src/matrix/datahndl.h | 109 ++ src/matrix/dbengnea.cpp | 1124 ++++++++++++ src/matrix/dbengneb.cpp | 522 ++++++ src/matrix/dmatrix.cpp | 18 + src/matrix/dmatrix.h | 149 ++ src/matrix/dvector.h | 168 ++ src/matrix/makeGraphics | 21 + src/matrix/makeGraphicsGPP | 21 + src/matrix/makeSamples | 18 + src/matrix/makeSamplesGPP | 18 + src/matrix/matbse.cpp | 1552 +++++++++++++++++ src/matrix/matbse.h | 208 +++ src/matrix/matgph.cpp | 529 ++++++ src/matrix/matrix.pro | 38 + src/matrix/matutl.cpp | 192 ++ src/matrix/mvaexit.cpp | 64 + src/matrix/mvaexit.h | 42 + src/matrix/mvagph.cpp | 1155 ++++++++++++ src/matrix/mvagph.h | 108 ++ src/matrix/mvaimpexp.h | 36 + src/matrix/mvalngbase.cpp | 443 +++++ src/matrix/mvalngbase.h | 118 ++ src/matrix/mvasamp1.cpp | 58 + src/matrix/mvasamp2.cpp | 82 + src/matrix/mvasamp3.cpp | 136 ++ src/matrix/mvasamp4.cpp | 133 ++ src/matrix/range.cpp | 253 +++ src/matrix/range.h | 98 ++ src/matrix/rangetst1.cpp | 47 + src/matrix/strctbse.cpp | 580 ++++++ src/matrix/strctbse.h | 134 ++ src/matrix/typehndl.h | 268 +++ src/matrix/under.cpp | 44 + src/matrix/under.h | 54 + src/matrix/vecbse.cpp | 1280 ++++++++++++++ src/matrix/vecbse.h | 203 +++ src/matrix/vecgph.cpp | 178 ++ src/matrix/vecutl.cpp | 227 +++ src/orbit/CVS/Entries | 10 + src/orbit/CVS/Repository | 1 + src/orbit/CVS/Root | 1 + src/orbit/Jamfile | 35 + src/orbit/Makefile | 269 +++ src/orbit/Orbit.cpp | 146 ++ src/orbit/Orbit.h | 251 +++ src/orbit/OrbitState.cpp | 166 ++ src/orbit/OrbitState.h | 204 +++ src/orbit/orbit.pro | 35 + src/orbit/orbitframes/CVS/Entries | 11 + src/orbit/orbitframes/CVS/Repository | 1 + src/orbit/orbitframes/CVS/Root | 1 + src/orbit/orbitframes/OrbitFrame.cpp | 27 + src/orbit/orbitframes/OrbitFrame.h | 91 + src/orbit/orbitframes/OrbitFrameECEF.cpp | 26 + src/orbit/orbitframes/OrbitFrameECEF.h | 63 + src/orbit/orbitframes/OrbitFrameEQW.h | 94 + src/orbit/orbitframes/OrbitFrameIJK.h | 76 + src/orbit/orbitframes/OrbitFrameNTW.h | 88 + src/orbit/orbitframes/OrbitFramePQW.h | 95 + src/orbit/orbitframes/OrbitFrameRSW.h | 78 + src/orbit/orbitframes/OrbitFrameSEZ.h | 67 + src/orbit/orbitmodels/CVS/Entries | 2 + src/orbit/orbitmodels/CVS/Repository | 1 + src/orbit/orbitmodels/CVS/Root | 1 + src/orbit/orbitmodels/TwoBodyDynamics.h | 128 ++ src/orbit/orbitstaterep/CVS/Entries | 7 + src/orbit/orbitstaterep/CVS/Repository | 1 + src/orbit/orbitstaterep/CVS/Root | 1 + src/orbit/orbitstaterep/Keplerian.cpp | 652 +++++++ src/orbit/orbitstaterep/Keplerian.h | 217 +++ .../OrbitStateRepresentation.cpp | 25 + .../orbitstaterep/OrbitStateRepresentation.h | 152 ++ src/orbit/orbitstaterep/PositionVelocity.cpp | 93 + src/orbit/orbitstaterep/PositionVelocity.h | 131 ++ src/rotation/CVS/Entries | 5 + src/rotation/CVS/Repository | 1 + src/rotation/CVS/Root | 1 + src/rotation/Jamfile | 31 + src/rotation/Rotation.cpp | 1505 ++++++++++++++++ src/rotation/Rotation.h | 541 ++++++ src/rotation/rotation.pro | 24 + src/test/AttitudeSimulatorServer.cpp | 280 +++ src/test/CVS/Entries | 14 + src/test/CVS/Repository | 1 + src/test/CVS/Root | 1 + src/test/HokieSatSimulation.cpp | 339 ++++ src/test/HokieSatSimulation.h | 57 + src/test/Makefile | 101 ++ src/test/testAttitudeIntegration.cpp | 222 +++ src/test/testDynamics.cpp | 93 + src/test/testEnvironment.cpp | 136 ++ src/test/testIntegration.cpp | 107 ++ src/test/testInterface.cpp | 483 +++++ src/test/testMatrix.cpp | 40 + src/test/testOrbitIntegration.cpp | 164 ++ src/test/testPropagation.cpp | 288 +++ src/test/testRotation.cpp | 103 ++ src/utils/CVS/Entries | 20 + src/utils/CVS/Repository | 1 + src/utils/CVS/Root | 1 + src/utils/Functor.h | 155 ++ src/utils/Integrator.h | 200 +++ src/utils/Interpolator.h | 152 ++ src/utils/Jamfile | 45 + src/utils/LinearInterpolator.cpp | 90 + src/utils/LinearInterpolator.h | 143 ++ src/utils/MathUtils.h | 127 ++ src/utils/Plot.cpp | 108 ++ src/utils/Plot.h | 130 ++ src/utils/RungeKutta.h | 106 ++ src/utils/RungeKuttaFehlbergIntegrator.cpp | 146 ++ src/utils/RungeKuttaFehlbergIntegrator.h | 78 + src/utils/RungeKuttaIntegrator.cpp | 179 ++ src/utils/RungeKuttaIntegrator.h | 81 + src/utils/Time.cpp | 195 +++ src/utils/Time.h | 525 ++++++ src/utils/TimeCompat.cpp | 72 + src/utils/math.pro | 32 + src/utils/utils.pro | 27 + 432 files changed, 60089 insertions(+) create mode 100644 CVS/Entries create mode 100644 CVS/Repository create mode 100644 CVS/Root create mode 100644 INSTALL create mode 100644 Jamfile create mode 100644 Jamrules create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README create mode 100644 VERSION create mode 100644 doc/About.h create mode 100644 doc/CVS/Entries create mode 100644 doc/CVS/Repository create mode 100644 doc/CVS/Root create mode 100644 doc/CodingStandards.h create mode 100644 doc/CommentStandards.h create mode 100644 doc/Intallation.h create mode 100644 doc/Introduction.h create mode 100644 doc/License.h create mode 100644 doc/Mainpage.h create mode 100644 doc/Makefile create mode 100644 doc/Tutorials.h create mode 100644 doc/UsingFramework.h create mode 100644 doc/doxyMatrix create mode 100644 doc/doxyfile create mode 100644 doc/html/AstroToolbox_8h-source.html create mode 100644 doc/html/AstroToolbox_8h.html create mode 100644 doc/html/Attitude_8h-source.html create mode 100644 doc/html/Attitude_8h.html create mode 100644 doc/html/CVS/Entries create mode 100644 doc/html/CVS/Repository create mode 100644 doc/html/CVS/Root create mode 100644 doc/html/Environment_8cpp.html create mode 100644 doc/html/Environment_8h-source.html create mode 100644 doc/html/Environment_8h.html create mode 100644 doc/html/Matrix_8cpp.html create mode 100644 doc/html/Matrix_8h-source.html create mode 100644 doc/html/Matrix_8h.html create mode 100644 doc/html/Orbit_8cpp.html create mode 100644 doc/html/Orbit_8h-source.html create mode 100644 doc/html/Orbit_8h.html create mode 100644 doc/html/Plot_8h-source.html create mode 100644 doc/html/Plot_8h.html create mode 100644 doc/html/RigidBody_8cpp.html create mode 100644 doc/html/RigidBody_8h-source.html create mode 100644 doc/html/RigidBody_8h.html create mode 100644 doc/html/Rotation_8cpp.html create mode 100644 doc/html/Rotation_8h-source.html create mode 100644 doc/html/Rotation_8h.html create mode 100644 doc/html/RungeKutta_8h-source.html create mode 100644 doc/html/RungeKutta_8h.html create mode 100644 doc/html/SpacecraftTime_8h-source.html create mode 100644 doc/html/SpacecraftTime_8h.html create mode 100644 doc/html/SpacecraftToolboxConstants_8h-source.html create mode 100644 doc/html/SpacecraftToolboxConstants_8h.html create mode 100644 doc/html/Spacecraft_8cpp.html create mode 100644 doc/html/Spacecraft_8h-source.html create mode 100644 doc/html/Spacecraft_8h.html create mode 100644 doc/html/Spacecraft__Sim_8cpp.html create mode 100644 doc/html/TestRotation_8cpp.html create mode 100644 doc/html/Trigonometry_8h-source.html create mode 100644 doc/html/Trigonometry_8h.html create mode 100644 doc/html/annotated.html create mode 100644 doc/html/bug.html create mode 100644 doc/html/classAttitude-members.html create mode 100644 doc/html/classAttitude.html create mode 100644 doc/html/classCEnvironment-members.html create mode 100644 doc/html/classCEnvironment.html create mode 100644 doc/html/classDirectionCosineMatrix-members.html create mode 100644 doc/html/classDirectionCosineMatrix.html create mode 100644 doc/html/classEnvironment-members.html create mode 100644 doc/html/classEnvironment.html create mode 100644 doc/html/classMatrix-members.html create mode 100644 doc/html/classMatrix.html create mode 100644 doc/html/classModifiedRodriguezParameters-members.html create mode 100644 doc/html/classModifiedRodriguezParameters.html create mode 100644 doc/html/classOrbit-members.html create mode 100644 doc/html/classOrbit.html create mode 100644 doc/html/classQuaternion-members.html create mode 100644 doc/html/classQuaternion.html create mode 100644 doc/html/classRigidBody-members.html create mode 100644 doc/html/classRigidBody.html create mode 100644 doc/html/classRotation-members.html create mode 100644 doc/html/classRotation.html create mode 100644 doc/html/classSpacecraft-members.html create mode 100644 doc/html/classSpacecraft.html create mode 100644 doc/html/classZeit-members.html create mode 100644 doc/html/classZeit.html create mode 100644 doc/html/doxygen.css create mode 100644 doc/html/doxygen.png create mode 100644 doc/html/files.html create mode 100644 doc/html/form_0.png create mode 100644 doc/html/form_1.png create mode 100644 doc/html/form_10.png create mode 100644 doc/html/form_11.png create mode 100644 doc/html/form_12.png create mode 100644 doc/html/form_13.png create mode 100644 doc/html/form_14.png create mode 100644 doc/html/form_15.png create mode 100644 doc/html/form_16.png create mode 100644 doc/html/form_17.png create mode 100644 doc/html/form_18.png create mode 100644 doc/html/form_19.png create mode 100644 doc/html/form_2.png create mode 100644 doc/html/form_20.png create mode 100644 doc/html/form_21.png create mode 100644 doc/html/form_3.png create mode 100644 doc/html/form_4.png create mode 100644 doc/html/form_5.png create mode 100644 doc/html/form_6.png create mode 100644 doc/html/form_7.png create mode 100644 doc/html/form_8.png create mode 100644 doc/html/form_9.png create mode 100644 doc/html/formula.repository create mode 100644 doc/html/functions.html create mode 100644 doc/html/globals.html create mode 100644 doc/html/group__Attitude.html create mode 100644 doc/html/group__AttitudeControl.html create mode 100644 doc/html/group__AttitudeRepresentation.html create mode 100644 doc/html/group__Constructors.html create mode 100644 doc/html/group__DCM.html create mode 100644 doc/html/group__DCMOperators.html create mode 100644 doc/html/group__DirectionCosineMatrix.html create mode 100644 doc/html/group__EOM.html create mode 100644 doc/html/group__FileAccess.html create mode 100644 doc/html/group__History.html create mode 100644 doc/html/group__MRP.html create mode 100644 doc/html/group__MRPOperators.html create mode 100644 doc/html/group__ModifiedRodriguezParameters.html create mode 100644 doc/html/group__Orbital.html create mode 100644 doc/html/group__OrbitalControl.html create mode 100644 doc/html/group__Physical.html create mode 100644 doc/html/group__Propagators.html create mode 100644 doc/html/group__Quaternion.html create mode 100644 doc/html/group__QuaternionOperators.html create mode 100644 doc/html/group__Rotation.html create mode 100644 doc/html/group__RotationInspectors.html create mode 100644 doc/html/group__RotationMutators.html create mode 100644 doc/html/group__RotationOperators.html create mode 100644 doc/html/group__SpacecraftFramework.html create mode 100644 doc/html/group__Trigonometry.html create mode 100644 doc/html/group__Zeit.html create mode 100644 doc/html/index.html create mode 100644 doc/html/main_8cpp.html create mode 100644 doc/html/modules.html create mode 100644 doc/html/namespaces.html create mode 100644 doc/html/namespacestd.html create mode 100644 doc/html/namespacetechsoft.html create mode 100644 doc/html/pages.html create mode 100644 doc/html/todo.html create mode 100644 packages/CVS/Entries create mode 100644 packages/CVS/Repository create mode 100644 packages/CVS/Root create mode 100644 packages/matrixLib.tar.gz create mode 100644 packages/rotationLib.tar.gz create mode 100644 src/CVS/Entries create mode 100644 src/CVS/Repository create mode 100644 src/CVS/Root create mode 100644 src/Jamfile create mode 100644 src/Makefile create mode 100644 src/SampleFile.cpp create mode 100644 src/attitude/Attitude.cpp create mode 100644 src/attitude/Attitude.h create mode 100644 src/attitude/AttitudeModels/CVS/Entries create mode 100644 src/attitude/AttitudeModels/CVS/Repository create mode 100644 src/attitude/AttitudeModels/CVS/Root create mode 100644 src/attitude/AttitudeModels/QuaternionAngVelDynamics.h create mode 100644 src/attitude/AttitudeState.cpp create mode 100644 src/attitude/AttitudeState.h create mode 100644 src/attitude/CVS/Entries create mode 100644 src/attitude/CVS/Repository create mode 100644 src/attitude/CVS/Root create mode 100644 src/attitude/Jamfile create mode 100644 src/attitude/Makefile create mode 100644 src/attitude/attitude.pro create mode 100644 src/datahandling/AttitudeHistory.cpp create mode 100644 src/datahandling/AttitudeHistory.h create mode 100644 src/datahandling/CVS/Entries create mode 100644 src/datahandling/CVS/Repository create mode 100644 src/datahandling/CVS/Root create mode 100644 src/datahandling/History.cpp create mode 100644 src/datahandling/History.h create mode 100644 src/datahandling/Jamfile create mode 100644 src/datahandling/Makefile create mode 100644 src/datahandling/OrbitHistory.cpp create mode 100644 src/datahandling/OrbitHistory.h create mode 100644 src/datahandling/datahandling.pro create mode 100644 src/dynamics/AnalyticPropagator.h create mode 100644 src/dynamics/CVS/Entries create mode 100644 src/dynamics/CVS/Repository create mode 100644 src/dynamics/CVS/Root create mode 100644 src/dynamics/CombinedNumericPropagator.cpp create mode 100644 src/dynamics/CombinedNumericPropagator.h create mode 100644 src/dynamics/Jamfile create mode 100644 src/dynamics/NumericPropagator.cpp create mode 100644 src/dynamics/NumericPropagator.h create mode 100644 src/dynamics/Propagator.cpp create mode 100644 src/dynamics/Propagator.h create mode 100644 src/dynamics/QuaternionDynamics.h create mode 100644 src/dynamics/dynamics.pro create mode 100644 src/environment/CVS/Entries create mode 100644 src/environment/CVS/Repository create mode 100644 src/environment/CVS/Root create mode 100644 src/environment/CentralBody/CVS/Entries create mode 100644 src/environment/CentralBody/CVS/Repository create mode 100644 src/environment/CentralBody/CVS/Root create mode 100644 src/environment/CentralBody/CentralBody.cpp create mode 100644 src/environment/CentralBody/CentralBody.h create mode 100644 src/environment/CentralBody/EarthCentralBody.cpp create mode 100644 src/environment/CentralBody/EarthCentralBody.h create mode 100644 src/environment/CentralBody/Models/CVS/Entries create mode 100644 src/environment/CentralBody/Models/CVS/Repository create mode 100644 src/environment/CentralBody/Models/CVS/Root create mode 100644 src/environment/CentralBody/Models/MagneticModel.h create mode 100644 src/environment/CentralBody/Models/TiltedDipoleMagneticModel.cpp create mode 100644 src/environment/CentralBody/Models/TiltedDipoleMagneticModel.h create mode 100644 src/environment/Disturbances/CVS/Entries create mode 100644 src/environment/Disturbances/CVS/Repository create mode 100644 src/environment/Disturbances/CVS/Root create mode 100644 src/environment/Disturbances/GravityFunctions.h create mode 100644 src/environment/Disturbances/SolarDisturbances.h create mode 100644 src/environment/Disturbances/ThirdBodyDisturbances.h create mode 100644 src/environment/Environment.cpp create mode 100644 src/environment/Environment.h create mode 100644 src/environment/Jamfile create mode 100644 src/environment/Makefile create mode 100644 src/environment/environment.pro create mode 100644 src/kinematics/CVS/Entries create mode 100644 src/kinematics/CVS/Repository create mode 100644 src/kinematics/CVS/Root create mode 100644 src/kinematics/QuaternionKinematics.h create mode 100644 src/matrix/CVS/Entries create mode 100644 src/matrix/CVS/Repository create mode 100644 src/matrix/CVS/Root create mode 100644 src/matrix/Jamfile create mode 100644 src/matrix/Makefile create mode 100644 src/matrix/Matrix.h create mode 100755 src/matrix/access.h create mode 100755 src/matrix/arraybse.cpp create mode 100755 src/matrix/arraybse.h create mode 100755 src/matrix/arraygph.cpp create mode 100755 src/matrix/arrayops.cpp create mode 100755 src/matrix/arrayutl.cpp create mode 100755 src/matrix/bnengine.h create mode 100644 src/matrix/camblas/CVS/Entries create mode 100644 src/matrix/camblas/CVS/Repository create mode 100644 src/matrix/camblas/CVS/Root create mode 100644 src/matrix/camblas/Jamfile create mode 100644 src/matrix/camblas/blas.cpp create mode 100644 src/matrix/camblas/blas.h create mode 100644 src/matrix/camblas/blasimpexp.h create mode 100644 src/matrix/camblas/cblasimpexp.h create mode 100644 src/matrix/camblas/cinterface.pdf create mode 100644 src/matrix/camblas/dasum.c create mode 100644 src/matrix/camblas/daxpy.c create mode 100644 src/matrix/camblas/dcopy.c create mode 100644 src/matrix/camblas/ddot.c create mode 100644 src/matrix/camblas/dgemm.c create mode 100644 src/matrix/camblas/dgemv.c create mode 100644 src/matrix/camblas/dger.c create mode 100644 src/matrix/camblas/dnrm2.c create mode 100644 src/matrix/camblas/drot.c create mode 100644 src/matrix/camblas/dscal.c create mode 100644 src/matrix/camblas/dswap.c create mode 100644 src/matrix/camblas/dsymv.c create mode 100644 src/matrix/camblas/dsyr2.c create mode 100644 src/matrix/camblas/dsyr2k.c create mode 100644 src/matrix/camblas/dtrmm.c create mode 100644 src/matrix/camblas/dtrmv.c create mode 100644 src/matrix/camblas/f2c.h create mode 100644 src/matrix/camblas/ilaenv.c create mode 100644 src/matrix/camblas/lsame.c create mode 100644 src/matrix/camblas/s_cmp.c create mode 100644 src/matrix/camblas/s_copy.c create mode 100644 src/matrix/camblas/xerbla.c create mode 100644 src/matrix/camlapack/CVS/Entries create mode 100644 src/matrix/camlapack/CVS/Repository create mode 100644 src/matrix/camlapack/CVS/Root create mode 100644 src/matrix/camlapack/Jamfile create mode 100644 src/matrix/camlapack/camlaimpexp.h create mode 100644 src/matrix/camlapack/d_lg10.c create mode 100644 src/matrix/camlapack/d_sign.c create mode 100644 src/matrix/camlapack/dgecon.c create mode 100644 src/matrix/camlapack/dgeequ.c create mode 100644 src/matrix/camlapack/dgerfs.c create mode 100644 src/matrix/camlapack/dgesvx.c create mode 100644 src/matrix/camlapack/dgetf2.c create mode 100644 src/matrix/camlapack/dgetrf.c create mode 100644 src/matrix/camlapack/dgetrs.c create mode 100644 src/matrix/camlapack/dlabad.c create mode 100644 src/matrix/camlapack/dlacon.c create mode 100644 src/matrix/camlapack/dlacpy.c create mode 100644 src/matrix/camlapack/dlamch.c create mode 100644 src/matrix/camlapack/dlange.c create mode 100644 src/matrix/camlapack/dlaqge.c create mode 100644 src/matrix/camlapack/dlassq.c create mode 100644 src/matrix/camlapack/dlaswp.c create mode 100644 src/matrix/camlapack/dlatrs.c create mode 100644 src/matrix/camlapack/drscl.c create mode 100644 src/matrix/camlapack/dtrsm.c create mode 100644 src/matrix/camlapack/dtrsv.c create mode 100644 src/matrix/camlapack/f2c.h create mode 100644 src/matrix/camlapack/i_dnnt.c create mode 100644 src/matrix/camlapack/idamax.c create mode 100644 src/matrix/camlapack/ilaenv.c create mode 100644 src/matrix/camlapack/pow_di.c create mode 100644 src/matrix/camlapack/s_cmp.c create mode 100644 src/matrix/camlapack/s_copy.c create mode 100755 src/matrix/cammva.h create mode 100755 src/matrix/camtype.h create mode 100755 src/matrix/darray.cpp create mode 100755 src/matrix/darray.h create mode 100755 src/matrix/datahndl.cpp create mode 100755 src/matrix/datahndl.h create mode 100755 src/matrix/dbengnea.cpp create mode 100755 src/matrix/dbengneb.cpp create mode 100755 src/matrix/dmatrix.cpp create mode 100755 src/matrix/dmatrix.h create mode 100755 src/matrix/dvector.h create mode 100755 src/matrix/makeGraphics create mode 100755 src/matrix/makeGraphicsGPP create mode 100755 src/matrix/makeSamples create mode 100755 src/matrix/makeSamplesGPP create mode 100755 src/matrix/matbse.cpp create mode 100755 src/matrix/matbse.h create mode 100755 src/matrix/matgph.cpp create mode 100644 src/matrix/matrix.pro create mode 100755 src/matrix/matutl.cpp create mode 100755 src/matrix/mvaexit.cpp create mode 100755 src/matrix/mvaexit.h create mode 100755 src/matrix/mvagph.cpp create mode 100755 src/matrix/mvagph.h create mode 100755 src/matrix/mvaimpexp.h create mode 100755 src/matrix/mvalngbase.cpp create mode 100755 src/matrix/mvalngbase.h create mode 100755 src/matrix/mvasamp1.cpp create mode 100755 src/matrix/mvasamp2.cpp create mode 100755 src/matrix/mvasamp3.cpp create mode 100755 src/matrix/mvasamp4.cpp create mode 100755 src/matrix/range.cpp create mode 100755 src/matrix/range.h create mode 100755 src/matrix/rangetst1.cpp create mode 100755 src/matrix/strctbse.cpp create mode 100755 src/matrix/strctbse.h create mode 100755 src/matrix/typehndl.h create mode 100755 src/matrix/under.cpp create mode 100755 src/matrix/under.h create mode 100755 src/matrix/vecbse.cpp create mode 100755 src/matrix/vecbse.h create mode 100755 src/matrix/vecgph.cpp create mode 100755 src/matrix/vecutl.cpp create mode 100644 src/orbit/CVS/Entries create mode 100644 src/orbit/CVS/Repository create mode 100644 src/orbit/CVS/Root create mode 100644 src/orbit/Jamfile create mode 100644 src/orbit/Makefile create mode 100644 src/orbit/Orbit.cpp create mode 100644 src/orbit/Orbit.h create mode 100644 src/orbit/OrbitState.cpp create mode 100644 src/orbit/OrbitState.h create mode 100644 src/orbit/orbit.pro create mode 100644 src/orbit/orbitframes/CVS/Entries create mode 100644 src/orbit/orbitframes/CVS/Repository create mode 100644 src/orbit/orbitframes/CVS/Root create mode 100644 src/orbit/orbitframes/OrbitFrame.cpp create mode 100644 src/orbit/orbitframes/OrbitFrame.h create mode 100644 src/orbit/orbitframes/OrbitFrameECEF.cpp create mode 100644 src/orbit/orbitframes/OrbitFrameECEF.h create mode 100644 src/orbit/orbitframes/OrbitFrameEQW.h create mode 100644 src/orbit/orbitframes/OrbitFrameIJK.h create mode 100644 src/orbit/orbitframes/OrbitFrameNTW.h create mode 100644 src/orbit/orbitframes/OrbitFramePQW.h create mode 100644 src/orbit/orbitframes/OrbitFrameRSW.h create mode 100644 src/orbit/orbitframes/OrbitFrameSEZ.h create mode 100644 src/orbit/orbitmodels/CVS/Entries create mode 100644 src/orbit/orbitmodels/CVS/Repository create mode 100644 src/orbit/orbitmodels/CVS/Root create mode 100644 src/orbit/orbitmodels/TwoBodyDynamics.h create mode 100644 src/orbit/orbitstaterep/CVS/Entries create mode 100644 src/orbit/orbitstaterep/CVS/Repository create mode 100644 src/orbit/orbitstaterep/CVS/Root create mode 100644 src/orbit/orbitstaterep/Keplerian.cpp create mode 100644 src/orbit/orbitstaterep/Keplerian.h create mode 100644 src/orbit/orbitstaterep/OrbitStateRepresentation.cpp create mode 100644 src/orbit/orbitstaterep/OrbitStateRepresentation.h create mode 100644 src/orbit/orbitstaterep/PositionVelocity.cpp create mode 100644 src/orbit/orbitstaterep/PositionVelocity.h create mode 100644 src/rotation/CVS/Entries create mode 100644 src/rotation/CVS/Repository create mode 100644 src/rotation/CVS/Root create mode 100644 src/rotation/Jamfile create mode 100755 src/rotation/Rotation.cpp create mode 100755 src/rotation/Rotation.h create mode 100644 src/rotation/rotation.pro create mode 100644 src/test/AttitudeSimulatorServer.cpp create mode 100644 src/test/CVS/Entries create mode 100644 src/test/CVS/Repository create mode 100644 src/test/CVS/Root create mode 100644 src/test/HokieSatSimulation.cpp create mode 100644 src/test/HokieSatSimulation.h create mode 100644 src/test/Makefile create mode 100644 src/test/testAttitudeIntegration.cpp create mode 100644 src/test/testDynamics.cpp create mode 100644 src/test/testEnvironment.cpp create mode 100644 src/test/testIntegration.cpp create mode 100644 src/test/testInterface.cpp create mode 100644 src/test/testMatrix.cpp create mode 100644 src/test/testOrbitIntegration.cpp create mode 100644 src/test/testPropagation.cpp create mode 100644 src/test/testRotation.cpp create mode 100644 src/utils/CVS/Entries create mode 100644 src/utils/CVS/Repository create mode 100644 src/utils/CVS/Root create mode 100644 src/utils/Functor.h create mode 100644 src/utils/Integrator.h create mode 100644 src/utils/Interpolator.h create mode 100644 src/utils/Jamfile create mode 100644 src/utils/LinearInterpolator.cpp create mode 100644 src/utils/LinearInterpolator.h create mode 100644 src/utils/MathUtils.h create mode 100644 src/utils/Plot.cpp create mode 100644 src/utils/Plot.h create mode 100644 src/utils/RungeKutta.h create mode 100644 src/utils/RungeKuttaFehlbergIntegrator.cpp create mode 100644 src/utils/RungeKuttaFehlbergIntegrator.h create mode 100644 src/utils/RungeKuttaIntegrator.cpp create mode 100644 src/utils/RungeKuttaIntegrator.h create mode 100644 src/utils/Time.cpp create mode 100644 src/utils/Time.h create mode 100644 src/utils/TimeCompat.cpp create mode 100644 src/utils/math.pro create mode 100644 src/utils/utils.pro diff --git a/CVS/Entries b/CVS/Entries new file mode 100644 index 0000000..c38a971 --- /dev/null +++ b/CVS/Entries @@ -0,0 +1,10 @@ +/INSTALL/1.2/Mon Sep 1 23:03:04 2003// +/Jamfile/1.2/Mon Dec 8 14:47:37 2003// +/Jamrules/1.9/Tue Jun 8 13:16:06 2004// +/LICENSE/1.1/Tue May 20 18:17:52 2003// +/Makefile/1.8/Wed May 21 03:45:58 2003// +/README/1.2/Thu Sep 23 18:59:39 2004// +/VERSION/1.1/Tue May 20 18:18:07 2003// +D/doc//// +D/packages//// +D/src//// diff --git a/CVS/Repository b/CVS/Repository new file mode 100644 index 0000000..380fecc --- /dev/null +++ b/CVS/Repository @@ -0,0 +1 @@ +spacecraft diff --git a/CVS/Root b/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..89f14a0 --- /dev/null +++ b/INSTALL @@ -0,0 +1,10 @@ +OPEN-SESSAME Version 1.0 + +Please read the installation section of the manual +(http://spacecraft.sourceforge.net/install.html) for instructions. + +Make sure to have QTDIR set to your local QT installation: +# export QTDIR=/usr/share/qt/ + +-------- +Andrew J. Turner (19 May 2003) diff --git a/Jamfile b/Jamfile new file mode 100644 index 0000000..ca5a0d3 --- /dev/null +++ b/Jamfile @@ -0,0 +1,28 @@ +############################################ +# Top level Jamfile for OSESSAME +# +# $Author: simpliciter $ +# $Revision: 1.2 $ +# $Date: 2003/12/08 14:47:37 $ +# +############################################ + +# This SubDir defines the project root directory +SubDir OPENSESSAME_ROOT ; + +# Only include the next level down in the tree +SubInclude OPENSESSAME_ROOT src ; + + +## Do not change the comments below - they will be added automatically by CVS +############################################################################# +# $Log: Jamfile,v $ +# Revision 1.2 2003/12/08 14:47:37 simpliciter +# All new Jamfiles! +# +# +# +############################################################################# + + + diff --git a/Jamrules b/Jamrules new file mode 100644 index 0000000..2d6c67c --- /dev/null +++ b/Jamrules @@ -0,0 +1,78 @@ +################################################## +# Jamrules file for OPENSESSAME +# +# $Author: simpliciter $ +# $Revision: 1.9 $ +# $Date: 2004/06/08 13:16:06 $ +# +############################################ + +OPENSESSAME_LIBDIR = $(OPENSESSAME_ROOT)$(SLASH)lib ; +OPENSESSAME_INCLUDEDIR = $(OPENSESSAME_ROOT)$(SLASH)include ; +OPENSESSAME_BINDIR = $(OPENSESSAME_ROOT)$(SLASH)bin ; +PFXLIB = libosessame_ ; + +OPENSESSAME_HDRS = $(OPENSESSAME_ROOT)$(SLASH)src $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)attitude $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)datahandling $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)dynamics $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)environment $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)orbit $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)rotation $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)matrix ; + +# Add OS dependendent libraries +if $(MSVCNT) +{ + ECHO "Compiler is Microsoft Visual C++" ; + CCFLAGS += /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c ; + C++FLAGS = $(CCFLAGS) ; + NOARSCAN ?= true ; + + LINKFLAGS += /D "WIN32" ; + + #SubInclude OPENSESSAME_ROOT src MSWindows_Dependent_Dir ; +} +else if $(UNIX) +{ + CC = gcc ; + C++ = g++ ; + ECHO "Compiler is" $(C++) ; + CCFLAGS += -Wno-deprecated ; + C++FLAGS = $(CCFLAGS) ; +} + + + + +rule Document +{ +# Depends $(1) : $(DOXYFILE) ; + Dox doc : $(DOXYFILE) ; +} +actions Dox +{ + doxygen $(2) +} + + + +## Do not change the comments below - they will be added automatically by CVS +############################################################################# +# $Log: Jamrules,v $ +# Revision 1.9 2004/06/08 13:16:06 simpliciter +# Changed explicit dependency on gcc-3.3, as that's the default gcc on most systems now. +# +# Revision 1.8 2003/12/09 00:58:54 simpliciter +# Removed explicit /utils dir call. +# +# Revision 1.7 2003/12/08 16:49:18 simpliciter +# Final fix for typhon compatibility. +# +# Revision 1.6 2003/12/08 15:00:42 simpliciter +# Correct gcc version for typhon. +# +# Revision 1.5 2003/12/08 14:47:37 simpliciter +# All new Jamfiles! +# +# +# +############################################################################# + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..219ec28 --- /dev/null +++ b/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) yyyy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) yyyy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1b99961 --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +# Spacecraft Simulation Framework +# Makefile +# +# $Author: nilspace $ +# $Revision: 1.8 $ +# $Date: 2003/05/21 03:45:58 $ + +# Which compiler to use +CC = gcc +CFLAGS = -g -Wall $(INCLUDE) -Wno-deprecated + +all: qmake src/Makefile doc + $(MAKE) -C src/ all + +doc: FORCE + $(MAKE) -C doc/ all + +qmake: + $(MAKE) -C src/ qmake + +clean: + $(MAKE) -C src/ clean + $(MAKE) -C doc/ clean +archive: clean + tar zcvf OpenSessame`date +%y%m%d`.tgz doc src Makefile INSTALL LICENSE VERSION + +FORCE: +# /***************************************************************************** +# * $Log: Makefile,v $ +# * Revision 1.8 2003/05/21 03:45:58 nilspace +# * Update to work. +# * +# * Revision 1.7 2003/05/20 19:12:54 nilspace +# * Updated to call qmake. +# * +# * Revision 1.6 2003/05/15 20:48:51 simpliciter +# * removed explicit gcc-3.1 call +# * +# * Revision 1.5 2003/05/15 19:49:20 simpliciter +# * Passing CFLAGS to sub-Makefiles. +# * +# * Revision 1.4 2003/05/15 19:47:07 simpliciter +# * Added -Wno-deprecated to CFLAGS line to suppress error messages. +# * +# * Revision 1.3 2003/05/15 19:38:21 simpliciter +# * Sub-Makefiles will be called with the CC identified at the top of this file. +# * +# * Revision 1.2 2003/05/15 18:41:39 nilspace +# * Updated the clean: target. +# * +# * Revision 1.1 2003/05/01 15:02:12 nilspace +# * New makefile for building the Open-SESSAME libraries and documentation. +# * +# * +# ******************************************************************************/ diff --git a/README b/README new file mode 100644 index 0000000..109a330 --- /dev/null +++ b/README @@ -0,0 +1,22 @@ +OPEN-SESSAME Framework Version 1.0 + +IMPORTANT: I am looking for feedback on users of Open-SESSAME. I see that there has been a lot of download activity on the sourceforge webpage. If you have downloaded Open-SESSAME, and are giving it a try *PLEASE* send me an email regarding your usage and what you are planning to do with it. Development has currently paused as I don't know who is using Open-SESSAME and what features they would like to use. + +Please read INSTALL for compilation instructions. + +The latest version of the Open-Sessame Framework can be obtained at + http://spacecraft.sourceforge.net/ + +There are two mailing lists + spacecraft-users@lists.sourceforge.net + spacecraft-develop@lists.sourceforge.net + +please follow the link in + + http://sourceforge.net/projects/spacecraft + +to subscribe to the lists or to visit the archives. + +Enjoy, + +Andrew J. Turner (nilspace@sourceforge.net) (19 May 2003) diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..d3827e7 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0 diff --git a/doc/About.h b/doc/About.h new file mode 100644 index 0000000..7d87f21 --- /dev/null +++ b/doc/About.h @@ -0,0 +1,8 @@ +/*! \page AboutPage About Open-Sessame + + @authors No one yet. + \ref IntroductionPage + + This page introduces the development team, project history, the associated lab, etc. + + */ diff --git a/doc/CVS/Entries b/doc/CVS/Entries new file mode 100644 index 0000000..de7d1fb --- /dev/null +++ b/doc/CVS/Entries @@ -0,0 +1,13 @@ +/About.h/1.1/Tue May 20 19:14:21 2003// +/CodingStandards.h/1.3/Mon Sep 1 23:03:04 2003// +/CommentStandards.h/1.2/Tue May 20 19:14:21 2003// +/Intallation.h/1.3/Tue Jun 10 15:17:31 2003// +/Introduction.h/1.1/Tue May 20 19:14:21 2003// +/License.h/1.1/Tue May 20 19:14:21 2003// +/Mainpage.h/1.3/Mon Sep 1 23:03:04 2003// +/Makefile/1.2/Mon Sep 1 23:03:04 2003// +/Tutorials.h/1.4/Wed Jun 11 14:24:22 2003// +/UsingFramework.h/1.1/Tue May 20 19:14:21 2003// +/doxyMatrix/1.1/Fri Feb 28 20:07:21 2003// +/doxyfile/1.5/Mon Sep 1 23:03:04 2003// +D/html//// diff --git a/doc/CVS/Repository b/doc/CVS/Repository new file mode 100644 index 0000000..aac9b2e --- /dev/null +++ b/doc/CVS/Repository @@ -0,0 +1 @@ +spacecraft/doc diff --git a/doc/CVS/Root b/doc/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/doc/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/doc/CodingStandards.h b/doc/CodingStandards.h new file mode 100644 index 0000000..9b65169 --- /dev/null +++ b/doc/CodingStandards.h @@ -0,0 +1,101 @@ +/*! \page CodingStandardsPage Coding Standards +\ref mainpage + +\verbatim + +#ifndef CLASSTEMPLATE_H +#define CLASSTEMPLATE_H + +// [C Headers] +extern "C" { +} + +// [C++ Header files] +#include "SomeClass.h" + +// [forward declarations] +class AnotherClass; + +%/** +* @class ClassTemplate +* +* @brief This is an example class. +* +* This comment block is @e required for all class declarations. +* Please remove comments that are bracketed by [..]. These comments are there +* to provide instructions to developers while writing their code. +* Obvious member variables and functions, such as get and set routines and +* default constructors and destructors, should not be documented as this +* clutters the files. Use standard C++ comments for those comments you wish +* Doxygen to ignore. If the class has many members - you may consider +* providing separate public, protected, private sections for member functions +* and member variables to improve readability. In addition it may be useful to +* form member groups preceded by a header as shown below. +* +* Please note that the \$Header\$ keyword specified below is a RCS keyword, +* and will inflate into the version, name, etc for this file. +* +* @author Some Body +* +* $Header $ +*/ + +class ClassTemplate { + +public: +ClassTemplate(); +~ClassTemplate(); + +int getIntMember() { return m_intMember; }; +void setIntMember(const int i) { m_intMember = i; }; + +%/** +* Provide detailed desciption of this function +* @param parmeter1 Describe this parameter + +* Here is an example of inserting a mathematical formula into the text: +* The distance is computed as /f$\sqrt{ (x_2-x_1)^2 + (y_2 - y_1)^2 }/f$ +* If we wanted to insert the formula centered on a separate line: +* /f[ +* \sqrt{ (x_2-x_1)^2 + (y_2 - y_1)^2 } +* /f] +* Please note that all formulas must be valid LaTeX math-mode commands. +* Additionally, to be processed by Doxygen, the machine used must have +* LaTeX installed. Please see the Doxygen manual for more information +* about installing LaTeX locally. +*/ +void publicMemberFunction(int parameter1); + +%/** +* Provide a detailed description of this function. +* @return Describe the return values. +*/ +bool anotherPublcMemberFunction(); + +static int getStaticIntMember() { return s_staticIntMember; }; + +%/** @name Header for Group1 +* [ Description of Group1 ] +*/ +//@{ +// [ members of Group1] +bool yetAnotherFunction1(); +int yetAnotherFunction2(); +//@} + +private: + +/// Provide a description of this class member +/// [note that the m_ prefix is not used for static members] +static int s_staticIntMember; +/// Provide a description of this class member +int m_intMember; +/// Provide a description of this class member +float m_floatMember; + +} + +#endif // CLASSTEMPLATE_H +/*! +\endverbatim +*/ \ No newline at end of file diff --git a/doc/CommentStandards.h b/doc/CommentStandards.h new file mode 100644 index 0000000..424f399 --- /dev/null +++ b/doc/CommentStandards.h @@ -0,0 +1,102 @@ +/*! \page CommentStandardsPage Comments Standard +\ref mainpage + +\code + +#ifndef CLASSTEMPLATE_H +#define CLASSTEMPLATE_H + +// [C Headers] +extern "C" { +} + +// [C++ Header files] +#include "SomeClass.h" + +// [forward declarations] +class AnotherClass; + +/** +* @class ClassTemplate +* +* @brief This is an example class. +* +* This comment block is @e required for all class declarations. +* Please remove comments that are bracketed by [..]. These comments are there +* to provide instructions to developers while writing their code. +* Obvious member variables and functions, such as get and set routines and +* default constructors and destructors, should not be documented as this +* clutters the files. Use standard C++ comments for those comments you wish +* Doxygen to ignore. If the class has many members - you may consider +* providing separate public, protected, private sections for member functions +* and member variables to improve readability. In addition it may be useful to +* form member groups preceded by a header as shown below. +* +* Please note that the \$Header\$ keyword specified below is a RCS keyword, +* and will inflate into the version, name, etc for this file. +* +* @author Some Body +* +* $Header $ +*/ + +class ClassTemplate { + +public: +ClassTemplate(); +~ClassTemplate(); + +int getIntMember() { return m_intMember; }; +void setIntMember(const int i) { m_intMember = i; }; + +/** +* Provide detailed desciption of this function +* @param parmeter1 Describe this parameter + +* Here is an example of inserting a mathematical formula into the text: +* The distance is computed as /f$\sqrt{ (x_2-x_1)^2 + (y_2 - y_1)^2 }/f$ +* If we wanted to insert the formula centered on a separate line: +* /f[ +* \sqrt{ (x_2-x_1)^2 + (y_2 - y_1)^2 } +* /f] +* Please note that all formulas must be valid LaTeX math-mode commands. +* Additionally, to be processed by Doxygen, the machine used must have +* LaTeX installed. Please see the Doxygen manual for more information +* about installing LaTeX locally. +*/ +void publicMemberFunction(int parameter1); + +/** +* Provide a detailed description of this function. +* @return Describe the return values. +*/ +bool anotherPublcMemberFunction(); + +static int getStaticIntMember() { return s_staticIntMember; }; + +/** @name Header for Group1 +* [ Description of Group1 ] +*/ +//@{ +// [ members of Group1] +bool yetAnotherFunction1(); +int yetAnotherFunction2(); +//@} + +private: + +/// Provide a description of this class member +/// [note that the m_ prefix is not used for static members] +static int s_staticIntMember; +/// Provide a description of this class member +int m_intMember; +/// Provide a description of this class member +float m_floatMember; + +} + +#endif // CLASSTEMPLATE_H + +/*! +\endcode +*/ \ No newline at end of file diff --git a/doc/Intallation.h b/doc/Intallation.h new file mode 100644 index 0000000..cac4e31 --- /dev/null +++ b/doc/Intallation.h @@ -0,0 +1,49 @@ +/*! \page InstallationPage Installation Instructions +\ref TableOfContents : \ref IntroductionPage + + This page contains installation instructions for \ref LinuxInstall, \ref WindowsInstall, \ref EmbeddedComputersInstall, + and \ref InstallingLibraries. + \par + For more info see section \ref TroubleshootingInstallation. + + \section Requirements + The following programs are required or suggested for using and developing with the Open-Sessame Framework: + - Doxygen + - GraphViz (Another) + - GNU GCC + - GnuPlot + - CVS + + \section Building Building the libraries + \subsection LinuxInstall Linux + -# Grab the current software via 2 methods, CVS or a bundled ZIP file: + -# CVS + - Make sure that CVS (Concurrent Versioning System) is installed on your system. + - Run the following command from the directory where you want to store the project files: \verbatim cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/spacecraft co spacecraft \endverbatim + - If you receive an error like: "cvs [checkout aborted]: recv() from server cvs.sourceforge.net" just keep trying to checkout, the anonymous server is over-worked. + -# ZIP File + - Download the source bunde from Files. + - Unzip the bundle or source file: \verbatim gunzip OpenSessame-##_bundle.zip \endverbatim (where ## is the current version number) + -# Change to the spacecraft root directory: \verbatim cd spacecraft/ \endverbatim + -# Run the make file to compile the libraries: \verbatim make \endverbatim + - If you see the following error: \begin{verbatim}make[2]: *** No rule to make target `/mkspecs/linux-g++/qmake.conf', needed by `Makefile'. Stop.\end{verbatim} it means + you don't have QT or qmake installed or the environment variable set. Make sure QT is installed and then type the following at the command line: + \begin{verbatim}export QTDIR="/usr/share/qt"\end{verbatim} + -# Compile the documentation: \verbatim make doc \endverbatim + -# Change to the test directory: \verbatim cd src/test/ \endverbatim + -# Build a test file: \verbatim make testPropagation \endverbatim + -# Run the test program. If it runs okay, your installation is finished: \verbatim ./testPropagation \endverbatim + \subsection WindowsInstall Windows + This section is forthcoming: Developer XB70 + \todo Document Windows installation + + \subsection EmbeddedComputersInstall Embedded Computers + This section is forthcoming, but should be similar to \ref LinuxInstall + + \section InstallingLibraries Installing Libraries + \todo Document Library installation +*/ + +/*! \page TroubleshootingInstallation Troubleshooting Installation + Troubleshooting information forthcoming. +*/ \ No newline at end of file diff --git a/doc/Introduction.h b/doc/Introduction.h new file mode 100644 index 0000000..7e356f4 --- /dev/null +++ b/doc/Introduction.h @@ -0,0 +1,91 @@ +/** @page IntroductionPage Introduction to the Open-Sessame Framework + +@authors Andrew Turner + +\ref TableOfContents + +@section intro Introduction +The goal of this project is to develop an Open-Source, Extensible Spacecraft Simulation +And Modeling Environment (Open-SESSAME) framework that can serve as a basis for satellite +modeling and analysis. The entire collection of code provides most of the tools, libraries +and structure necessary for simulating a wide-range of spacecraft while also allowing easy +extension for any further desired functionality. Also, by being open-source users are able +to investigate the design and operating of the code to reassure themselves of the validity +of the simulator. The Open-SESSAME framework is also an active project of the large and rapidly +growing open-source community. This allows new functionality to be disseminated to all current +and future users of the framework as it continues to grow and mature. + + +\section rationale Rationale +Many students and researchers of satellite dynamics and control must independently +develop a software simulations each time a new research project begins. These simulations +are typically built specifically for the research task at hand and not easily adaptable to +future projects. Furthermore, many students have little experience developing simulations, +and may not know where to begin, what to be concerned with, and how to best implement +components so they can be resuable between projects and other students and engineers. +The Open-Sessame framework addresses these issues by providing a common groundwork upon +which students can learn how simulators are implemented and develop their own components +for use in the framework for their own research. + +The Space Systems Simulation Laboratory +(SSSL) at Virginia Tech in Blacksburg, Virginia is working on a +number of projects that work to develop new methodologies for the simulation and analysis of +spacecraft and their associated systems. +These projects include both hardware and software simulation techniques that are used in +conjuction to better understand the interplay of satellite dynamics with novel control \& +sensing strategies. As a result of the various unique requirements of many of the projects, +a single commercial software package has not yet fulfilled the needs of the lab. An open-source +and extensible simulation framework creates a reusable basis for any future simulation projects +while also allowing the students and researchers the capacity to configure the simulation to +their unique specifications. Furthermore, they are able to interface the simulation software +with any other analysis package they may require for their research. + +\section using Using the Framework + +Here is the suggested path for using the Open-Sessame Framework. +-# If you haven't already, download the latest source and documentation from the Sourceforge +repository at http://sourceforge.net/projects/spacecraft. +Download either the newest bundle (under @em Files), or click on the link to @em CVS and follow the basic instructions to get the +most up-to-date release. +-# Scroll through the Primer Presentation which gives an +introduction and overview of some of the main concepts. +-# Read the \ref UsingOpenSESSAME documentation about the general usage of the framework. +-# Build \& install the libraries by following the \ref InstallationPage. +-# Follow the \ref TutorialsPage +-# Check out the forums at the Sourceforge website +for discussion on development, useful links, tutorials, etc. There is a user base out there, use it. +-# Begin contributing by checking out the todo list or talking to other uses in the forums. + +@section installSection Installation +See the \ref InstallationPage ["Installation Page"] for instructions on building \& installing +the Open-Sessame framework libraries. + +* \section ToDo To Do Items + +To help in development, as well as learning the framework, here is a current (5/12/03) list of major +todo implementation items. These consist of larger scale new feature and add-on implementation items +that have been identified by the development team, which differe from the bug-fixes and small todo items +found on the 'todo' page. While the small items need to be completed, if you're up to learning more about +C++ coding and the framework, it is suggested you look at one of these problems. + +* @todo +-# A better, faster, powerful matrix/vector library. Should handle all typical linear algebra +functionality (matrix mult, vector mult, matrix*vector mult, inverse, transpose, norm, etc). Error handling +would be nice with options for command line debugging (outputting the type/size of matrix, characterization +of error (wrong mult sizes, singular) and possibly where the error occured (function, code line). +-# More force functions: solar radiation pressure, advanced atmospheric model, higher-order +gravity model +-# More torque functions: magnetic field, higher-order gravity gradient, micrometeorites +-# Need to implement frames, both orbit \& attitude. +-# A store and restore mechanism. Needs to be cross-platform, prefer something like XML formatting. Also need to be able to export/import with MatLab, Satellite ToolKit (STK), Excel (CSV), and others. + +*
+* @section notes Release Notes +* release.notes +*
+* @section Requirements Requirements +* @verbinclude requirements +*
+\image html sflogo.png + +*/ \ No newline at end of file diff --git a/doc/License.h b/doc/License.h new file mode 100644 index 0000000..16402e8 --- /dev/null +++ b/doc/License.h @@ -0,0 +1,415 @@ +/*! \page LicensePage License +\ref TableOfContents + The Open-Sessame Framework is distributed under the GNU General Public License (GPL). For more information, refer to www.gnu.org. + +\section GPL General Public License +Available at: http://www.gnu.org/licenses/gpl.html + +

GNU GENERAL PUBLIC LICENSE

+

+Version 2, June 1991 + +

+ +
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
+59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+ + + +

Preamble

+ +

+ The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +

+

+ When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +

+

+ To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +

+

+ For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +

+

+ + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +

+

+ Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +

+

+ Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +

+

+ The precise terms and conditions for copying, distribution and +modification follow. + +

+ + +

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+ + +

+ +0. + This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". +

+ +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +

+ +1. + + You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. +

+ +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. +

+ +2. + You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: +

+ +

    + +
  • a) + + You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + +

    +

  • b) + You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + +

    +

  • c) + If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) +
+ +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. +

+ +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. +

+ +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +

+ +3. + You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + + + +

    + +
  • a) + Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + +

    +

  • b) + Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + +

    +

  • c) + Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) +
+ +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. +

+ +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. +

+ +4. + You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +

+ +5. + You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +

+ +6. + Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + +

+ +7. + If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. +

+ +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. +

+ +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. +

+ +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +

+ +8. + If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +

+ +9. + The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. +

+ +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +

+ + +10. + + If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + + +

NO WARRANTY

+ +

+ +11. + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +

+ +12. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + +

+ + +

END OF TERMS AND CONDITIONS

+ + +\section Preamble Source code preamble +The following code segment should go at the beginning (or at least in) all source code files distributed with the Open-Sessame Framework. + +\verbatim +Copyright (C) yyyy name of author + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +\endverbatim +*/ diff --git a/doc/Mainpage.h b/doc/Mainpage.h new file mode 100644 index 0000000..8aa5a7f --- /dev/null +++ b/doc/Mainpage.h @@ -0,0 +1,20 @@ +/** @mainpage Open-Sessame Framework + +

Open-Source, Extensible Spacecraft Simulation Framework

+ @authors Andrew Turner + +\section TableOfContents Table of Contents +- \ref IntroductionPage +- \ref UsingOpenSESSAME +- \ref InstallationPage +- \ref TutorialsPage +- Programming + - \ref ProgrammingRefresher + - \ref CommentStandardsPage + - \ref CodingStandardsPage +- \ref LicensePage +- \ref AboutPage + +\image html images/sflogo.png + +*/ \ No newline at end of file diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..9fa0378 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,54 @@ +# Spacecraft Simulation Framework +# Makefile +# +# $Author: nilspace $ +# $Revision: 1.2 $ +# $Date: 2003/09/01 23:03:04 $ + +# Which compiler to use +CC = gcc + +all: doxyfile + doxygen doxyfile + +archive: doxyfile + pushd html; tar -cvf OpenSessameDoc.tar *; mv *.tar ../; popd; + gzip OpenSessameDoc.tar; + +clean: + rm -rf html/ + rm -f doxygen.error + + +FORCE: +# /***************************************************************************** +# * $Log: Makefile,v $ +# * Revision 1.2 2003/09/01 23:03:04 nilspace +# * Updating to do a recursive build. +# * +# * Revision 1.1 2003/05/21 03:47:54 nilspace +# * New documentation makefile. +# * +# * Revision 1.7 2003/05/20 19:12:54 nilspace +# * Updated to call qmake. +# * +# * Revision 1.6 2003/05/15 20:48:51 simpliciter +# * removed explicit gcc-3.1 call +# * +# * Revision 1.5 2003/05/15 19:49:20 simpliciter +# * Passing CFLAGS to sub-Makefiles. +# * +# * Revision 1.4 2003/05/15 19:47:07 simpliciter +# * Added -Wno-deprecated to CFLAGS line to suppress error messages. +# * +# * Revision 1.3 2003/05/15 19:38:21 simpliciter +# * Sub-Makefiles will be called with the CC identified at the top of this file. +# * +# * Revision 1.2 2003/05/15 18:41:39 nilspace +# * Updated the clean: target. +# * +# * Revision 1.1 2003/05/01 15:02:12 nilspace +# * New makefile for building the Open-SESSAME libraries and documentation. +# * +# * +# ******************************************************************************/ diff --git a/doc/Tutorials.h b/doc/Tutorials.h new file mode 100644 index 0000000..70a2d3e --- /dev/null +++ b/doc/Tutorials.h @@ -0,0 +1,373 @@ +/*! \page TutorialsPage Tutorials + \ref TableOfContents : \ref IntroductionPage : \ref TutorialAnswersPage + + The following sections are sets of tutorials meant to lead the user through the basics of using the Open-Sessame Framework +all the way to creating a full spacecraft simulation application. Each section is a listing of a textual +description of the problem to be solved, followed by a reference to the answer sheet. Don't cheat! Following the +successful completion of each lesson, the user should move onto the next lesson until all the tutorials are complete. + +\par Running Tutorials: + To build and run a tutorial, (after writing your file, e.g. myFile.cpp) follow the following instructions: + -# Put the @em .cpp file in the @em spacecraft/src/test directory: + \verbatim cp myFile.cpp spacecraft/src/test + cd spacecraft/src/test\endverbatim + or use whatever method you choose for getting it there (ftp, sftp, scp, drag -n- drop, mv, etc.) + -# Build the program by running the generalized makefile with the target of your source file, minus the @em cpp extension: + \verbatim make myFile \endverbatim + -# Run the program in the same directory (the executable will be the same as the source file minus the extension): + \verbatim ./myFile \endverbatim + -# Debug the code (unless your implementation was perfect, then check your answers) + - If you need help check the suggested \ref ProgrammingTroubleshooting + + \section RotationTutorials Rotation Tutorials +-# Create a Quaternion that has the initial parameters (0.5,0.5,0.5,0.5). +-# Output this quaternion to the console in both quaternion and Modified Rodriguez Parameters (MRP) form. +-# Create a Direction Cosine Matrix corresponding to a 321 rotation with angles: 10, -30, 150 degrees. +-# Create 2 "Rotation"s that are intialized by the quaternion and Direction Cosine Matrix. +-# Determine the successive rotation of these two rotations and output to the console in DCM form. +-# Verify that the answer you got was the correct (expected) one. + +\ref TutorialAnswersPage + +\section UtilityTutorials Utility Tutorials +-# Create an ssfTime object, set the epoch to the current real time, and the stored 'current' time to 50 seconds later. Output both of these in DateTime and JulianDate format to the console. +-# Plot a Matrix of values corresponding to the \f$ f(x)=\sin{x}\f$ for \f$x=0:2\pi \f$ using the Open-Sessame GnuPlot interface. +-# Create a linear interpolation of the \f$\sin{}\f$ function using a step-size of 0.1 + +\ref TutorialAnswersPage + + \section AttitudeTutorials Attitude Tutorials +-# Create an AttitudeState object instance that is initialized to an aligned rotation in the Orbit-Inertial Frame (attitudeframe not yet implemented fully). +-# Integrate an attitude for 50 seconds using the following conditions: + - Quaternion Kinematics + - Euler's equations of motion + - Gravity-gradient torque disturbance + - Initial conditions of: \f$\bar{\bf q}_0 = [0,0,0,1]^{T}\f$ and \f$\omega_{0} = [0,0.1, -0.05]^{T} \frac{rad}{s}\f$. + - Principle Moments of Inertia: \f$[100, 300, 150]\f$ +-# Store the attitude to a text file. +-# Plot the attitude history using GnuPlot. +-# Store the attitude in DirectionCosineMatrix format in a MatLab file. + +\ref AttitudeTutorialAnswer + + \section OrbitTutorials Orbit Tutorials +-# Create an OrbitState object instance that is initialized to the current state of the spacestation in inertial coordinates. +-# Convert to ECEF coordinates and output to the console. +-# Integrate an orbit for 2 orbits using the following conditions: + - 2-body force function above the Earth (mass = 200 kg). + - Solar-radiation pressure force disturbance (assume constant \f$Area=20 m^2\f$). + - Initial conditions of: \f${\bf r}=[-5776.6, -157, 3496.9]^{T}\f$ (km) and \f${\bf v} = [-2.595, -5.651, -4.513]^{T}\f$ (km/s). +-# Store the position and velocity to a text file. +-# Plot the orbit position vector using GnuPlot. +-# Store the orbit Keplerian parameters in a MatLab file. + +\ref OrbitTutorialAnswer + +\section CoupledTutorials Coupled Attitude & Orbit Tutorials +-# Create an Environment object of the Earth using the above (Orbit \& Attitude) disturbance force \& torque functions. +-# Create a Propagator that will propagate the above Orbit \& Attitude objects and using the Environment object. + - Use a linear interpolator for the OrbitHistory. + - Use loose coupling (orbit independent of attitude, but attitude dependent on position). +-# Propagate the orbit and attitude for 2 orbits. +-# Plot the position and attitude using gnuplot. +-# Propagate another 2 orbits. +-# Add the new states to the previously made plots. + +\ref CoupledTutorialAnswer +*/ + +/*! \page TutorialAnswersPage Tutorial Answers Page + \ref TableOfContents : \ref IntroductionPage : \ref TutorialsPage + +\section RotationTutorialAnswer Rotation Tutorial Answer + +\code +// Create a Quaternion that has the initial parameters (0.5,0.5,0.5,0.5). +Quaternion myQuat(0.5, 0.5, 0.5, 0.5); + +// Output this quaternion to the console in both quaternion and MRP form +cout << myQuat; +cout << myQuat.GetMRP(); + +// Create a Direction Cosine Matrix corresponding to a 321 rotation with angles: 10, -30, 150 degrees. +DirectionCosineMatrix myDCM(10*RPD, -30*RPD, 150*RPD, 321); + +// Create 2 "Rotation"s that are intialized by the quaternion and Direction Cosine Matrix. +Rotation myRot1(myQuat); +Rotation myRot2(myDCM); + +// Determine the successive rotation of these two rotations and output to the console in DCM form. +cout << (myRot1 * myRot2).GetDCM(); + +// Verify that the answer you got was the correct (expected) one. +Matrix Answer(3,3); + +\endcode + +Back to: \ref RotationTutorials +
+ +\section UtilityTutorialAnswer Utility Tutorial Answer +-# Create an ssfTime object, set the epoch to the current real time, and the stored 'current' time to 50 seconds later. Output both of these in DateTime and JulianDate format to the console. +\code +ssfTime myTime; +myTime.SetEpoch(Now()); +myTime.Set(myTime.GetEpoch() + 50); +cout << myTime.GetDateTime().tm_mon << "/" << myTime.GetDateTime().tm_mday << "/" << myTime.GetDateTime().tm_year << endl; +cout << myTime.GetJulianDate() << endl; +\endcode + +-# Plot a Matrix of values corresponding to the \f$ f(x)=\sin{x}\f$ for \f$x=0:2\pi \f$ using the Open-Sessame GnuPlot interface. +\code +int stepsize = 0.1; +Matrix datavec(2*M_PI / stepsize,2); +for (int jj = 1; jj <= datavec[MatrixRowsIndex].getIndexBound(); ++jj) +{ + datavec(jj,1) = jj * stepsize; + datavec(jj,2) = sin(jj * stepsize); +} +Plot2D(datavec); +\endcode +-# Create a linear interpolation of the \f$\sin{}\f$ function using a step-size of 0.1 +\code +int stepsize = 0.1; +Vector timeVec(2*M_PI / stepsize); +Matrix dataMat(timeVec[MatrixRowsIndex].getIndexBound(), 1); +for (int jj = 1; jj < timeVec[MatrixRowsIndex].getIndexBound(); ++jj) +{ + timeVec(jj) = jj * stepsize; + dataMat(jj,1) = sin(jj * stepsize); +} + +LinearInterpolator interp(timeVec,dataMat); +Vector chk = interp.Evaluate(0.25); +cout << timevec << endl << datavec << endl << sin(0.25) << " = " << chk << endl; +\endcode +Back to: \ref UtilityTutorials +
+ +\section AttitudeTutorialAnswer Attitude Tutorial Answer +-# Create an AttitudeState object instance that is initialized to an aligned rotation in the Orbit-Inertial Frame (attitudeframe not yet implemented fully). +\code +AttitudeState myAttState(Rotation(), new AttitudeFrameOI); +\endcode + +-# Integrate an attitude for 50 seconds using the following conditions: + +First setup the kinematics equation: +\code +static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + // Initialize the vectors used in the calculation. + // made static, which causes the memory to be allocated the first time the function is called + // and then left in memory during the program to speed up computation. + static Vector stateDot(7); + static Matrix bMOI(3,3); + static Matrix qtemp(4,3); + static Matrix Tmoment(3,1); + static Vector qIn(4); + static Vector wIn(3); + + // Retrieve the current integration states to a quaternion and angular velocity vector + qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3)); + wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6)); + qIn /= norm2(qIn); + + // Calculate qDot + qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3); + qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2))); + qtemp(_,MatrixIndexBase) = 0.5 * qtemp * wIn; + + // Get the moments of inertia and calculate the omegaDot + bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2)); + Tmoment = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn))); + + // Combine the qDot and omegaDot into a stateDot vector + stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = qtemp(_,MatrixIndexBase); + stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = Tmoment(_,MatrixIndexBase); + + return stateDot; +} +\endcode + +Then setup the driver code to run the above dynamics equation: +\code +// Setup an integrator and any special parameters +RungeKuttaIntegrator myIntegrator; +myIntegrator.SetNumSteps(1000); +// Integration times +vector integrationTimes; +ssfTime begin(0); +ssfTime end(begin + 50); +integrationTimes.push_back(begin); +integrationTimes.push_back(end); + +// Create the initial attitude state +AttitudeState myAttitudeState; +myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1))); +Vector initAngVelVector(3); + initAngVelVector(1) = 0; + initAngVelVector(2) = 0.1; + initAngVelVector(2) = -0.5; +myAttitudeState.SetAngularVelocity(initAngVelVector); +SpecificFunctor AttitudeForcesFunctor(&NullFunctor); + +// Create the matrix of parameters needed for the RHS - MOI +Matrix Parameters = eye(3); + Parameters(1) = 100; + Parameters(2) = 300; + Parameters(3) = 150; + +// Integrate over the desired time interval +Matrix history = myIntegrator.Integrate( + integrationTimes, // seconds + &AttituteDynamics, + myAttitudeState.GetState(), + NULL, + NULL, + Parameters, + AttitudeForcesFunctor + ); +\endcode +-# Store the attitude to a text file. +\code +ofstream ofile; +ofile.open("AttitudeHistory.dat"); +ofile << history; +ofile.close(); +\endcode + +-# Plot the attitude history using GnuPlot. +\code +Matrix plotting = history(_,_(MatrixIndexBase,MatrixIndexBase+4)); +Plot2D(plotting); +\endcode + +-# Store the attitude in DirectionCosineMatrix format in a MatLab file. + +Back to: \ref AttitudeTutorials +
+ +\section OrbitTutorialAnswer Orbit Tutorial Answer +Setup the dynamic equations: +\code +static Vector TwoBodyDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + static Vector Forces(3); + static Vector Velocity(3); + static Vector stateDot(6); + static AttitudeState tempAttState; // don't need this except to pass an empty one if there is no attitude + static OrbitState orbState(new PositionVelocity); + + orbState.GetStateRepresentation()->SetPositionVelocity(_integratingState); + + if(_Attitude) + Forces = _forceFunctorPtr.Call(_time, orbState, _Attitude->GetStateObject()); + else + Forces = _forceFunctorPtr.Call(_time, orbState, tempAttState); + + Velocity(_) = _integratingState(_(VectorIndexBase+3,VectorIndexBase+5)); + + + stateDot(_(VectorIndexBase, VectorIndexBase+2)) = Velocity(_); + stateDot(_(VectorIndexBase+3, VectorIndexBase+5)) = Forces(_); + return stateDot; +} +\endcode +The force functions are setup as follows (using drag instead of solar radiation pressure): +\code +Vector OrbitForcesWithDragFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState) +{ + Vector Forces; + Vector Position(3); Position(_) = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase,VectorIndexBase+2)); + + double BC = 0.5; + Vector Vrel(3); Vrel = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase+3,VectorIndexBase+5)); + double Vrel_mag = norm2(Vrel); + Forces = -398600.4418 / pow(norm2(Position),3) * Position; + + Forces += -1/2 *1/BC * pow(Vrel_mag,2) * Vrel / Vrel_mag; + return Forces; +} +\endcode + +Finally create the driver program and call the integration: +\code +// Setup an integrator and any special parameters +RungeKuttaIntegrator myIntegrator; + int numOrbits = 2; + int numSteps = 100; +myIntegrator.SetNumSteps(numSteps); + +vector integrationTimes; +ssfTime begin(0); +ssfTime end(begin + 92*60*numOrbits); +integrationTimes.push_back(begin); +integrationTimes.push_back(end); + +OrbitState myOrbitState; +myOrbitState.SetStateRepresentation(new PositionVelocity); +myOrbitState.SetOrbitFrame(new OrbitFrameIJK); +Vector initPV(6); + initPV(VectorIndexBase+0) = -5776.6; // km/s + initPV(VectorIndexBase+1) = -157; // km/s + initPV(VectorIndexBase+2) = 3496.9; // km/s + initPV(VectorIndexBase+3) = -2.595; // km/s + initPV(VectorIndexBase+4) = -5.651; // km/s + initPV(VectorIndexBase+5) = -4.513; // km/s +myOrbitState.GetStateRepresentation()->SetPositionVelocity(initPV); + +Matrix history = myIntegrator.Integrate( + integrationTimes, // seconds + &TwoBodyDynamics, + myOrbit.GetStateRepresentation()->GetPositionVelocity(), + NULL, + NULL, + Parameters, + OrbitForcesFunctor + ); +\endcode + +-# Store the position and velocity to a text file. +\code +ofstream ofile; +ofile.open("OrbitHistory.dat"); +ofile << history; +ofile.close(); +\endcode + +-# Plot the orbit position vector using GnuPlot. +\code +// Create the plot using Columns 2:4 +Matrix orbitHistory = myOrbit->GetHistory().GetHistory(); +Matrix orbitPlotting = orbitHistory(_,_(2,4)); +Plot3D(orbitPlotting); +\endcode +Here is a check for your answer (without solar radiation pressure): +\verbatim +[ time, r1, r2, r3, v1, v2, v3] +[ 5400, -5386.654, 562.845, 4034.074, -3.518027, -5.617977, -3.890888 ] +\endverbatim + +-# Store the orbit Keplerian parameters in a MatLab file. + +Back to: \ref OrbitTutorials + +\section CoupledTutorialAnswer Coupled Tutorial Answers +-# Create an Environment object of the Earth using the above (Orbit \& Attitude) disturbance force \& torque functions. + +-# Create a Propagator that will propagate the above Orbit \& Attitude objects and using the Environment object. + - Use a linear interpolator for the OrbitHistory. + - Use loose coupling (orbit independent of attitude, but attitude dependent on position). + +-# Propagate the orbit and attitude for 2 orbits. + +-# Plot the position and attitude using gnuplot. + +-# Propagate another 2 orbits. + +-# Add the new states to the previously made plots. + +Back to: \ref CoupledTutorials + +*/ diff --git a/doc/UsingFramework.h b/doc/UsingFramework.h new file mode 100644 index 0000000..7ce434e --- /dev/null +++ b/doc/UsingFramework.h @@ -0,0 +1,52 @@ +/*! \page UsingOpenSESSAME Using the Open-SESSAME Framework +\ref TableOfContents +
+ This section is meant to describe the design philosophy and methodology behind the Open-Source, Extensible Spacecraft Simulation And Modeling Environment Framework. It should give the reader a better understanding of the design of the framework and how to use it. + + \section Philosophy + No, this section is not for expounding upon the virtues of Plato or Kant or Nietzsche. What it is mean to convey is the philosophy behind the development of, and developing simulations with, the Open-SESSAME Framework. Hopefully this will give you a little better insight into the design of the framework, and how best to use, maintain, and extend it. + + First off, I think it is important to lay out the actual title of the framework: + - Open-Source - the source is free (as in beer) and available for users and developers. Changes are propagated back to the community via the publicly hosted repository so the software continues to grow \& mature. + + - Extensible - the framework is designed with the premise that functionality will be added as necessary by new users and developers. The code is plainly written and well-documented to ease understanding of the source, and also encourages development via @em hotspots, points which assist in adding functionality (ie environmental disturbance functions, dynamic equations, kinematic representations, etc.) + + - Spacecraft - Open-SESSAME is developed with the target of simulating spacecraft and satellites in outer space. While there are generic mathematical and operational toolboxes (matrix, rotation, XML storage) as part of the software package, these libraries were developed or interfaced with the given goal in mind. + + - Simulation And Modeling - Simulation is providing a user with a non-real, but approximated environment that accurately corresponds to the real-world. Modeling is the creation of the physical dynamics and characteristics of this simulated world. Open-SESSAME is meant to be used as both a stand-alone model of spacecraft, and for use in creating simulations which interact with hardware and other software programs. + + - Environment - the environment is the entire collection of dynamics, disturbances, data handling operations and interfaces that allow the user to interact with the simulation. + + - Framework - Open-SESSAME is a framework. It provides the tools and libraries that are combined together to create a simulation environment. By themselves they do not constitute an application, but must be joined by the user/developer in a meaningful way to simulate and analyze their particular problem. + + \section Methodology + So how do you actually create a simulation? A complete Open-Sessame simulation application (remember, Open-Sessame is just a framework, it is up to you to develop the application) consists of the following parts: + - Attitude dynamics equation + - Attitude kinematics equation + - Orbit dynamics equation + - Environmental disturbance torque \& force functions (may include a central body) + - Physical object definition (mass, moments of inertia, ballistic coefficient, etc) + - Propagator defining the coupling of the attitude \& orbit dynamics + - Integrators (both orbital & attitude) and Interpolators + - Data handling (history, saving, restoring, graphical output, input) + - Communications (only if running on distributed machines or using hardware) + + Each of these components is implemented in one of the various toolboxes that compose the Open-Sessame Framework. The user must build the appropriate component (for example, writing the right-hand side of the attitude dynamics equation using momentum wheels) using the toolboxes and examples. These are then brought together in a main function to facilitate communication between the components to run the simulation. See \ref Examples for more help. + + \section Components Framework Components + Below is a UML-esque diagram showing the Open-Sessame simulation application architecture. Components are color coded as follows: + - @em Purple: #RotationLibrary + - @em Blue: Attitude toolkit + - @em Pink: Orbit toolkit + - @em Green: Environment library + - @em Brown: Dynamics library + - @em Yellow: Data Handling library + + \image html Open-SESSAME_Architecture.jpg + \image latex Open-SESSAME_Architecture.pdf "Open-Sessame Framework Architecture" + + Simple arrows indicate a "@em has-a" relationship (OrbitState has an OrbitRep and an OrbitFrame). + Empty arrow heads indicate a derived class, or "@em is-a" (Quaternion is a Vector), and therefore has all the same functionality of the base class (Quaternion has all the funcionality of a Vector, as well as any more implemented in the Quaternion class itself). + + The components (each of the boxes) are coupled as shown to implement an actual spacecraft simulation application for modeling \& analysis. +*/ diff --git a/doc/doxyMatrix b/doc/doxyMatrix new file mode 100644 index 0000000..fba5597 --- /dev/null +++ b/doc/doxyMatrix @@ -0,0 +1,969 @@ +# Doxyfile 1.2.17 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "Matrix Library" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = "v0.1" + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = "" + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = "doxyMatrix.error" + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = "../src/matrix" + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html/matrix + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non empty doxygen will try to run +# the html help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, +# or Internet explorer 4.0+). Note that for large projects the tree generation +# can take a very long time. In such cases it is better to disable this feature. +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = amsmath + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/doc/doxyfile b/doc/doxyfile new file mode 100644 index 0000000..6a6c59e --- /dev/null +++ b/doc/doxyfile @@ -0,0 +1,971 @@ +# Doxyfile 1.2.17 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "Open-Sessame Framework" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = "v1.0" + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = "" + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = NO + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = "codeExample=\par Examples:\n" + +#ALIASES += "example=\xrefitem example \"Examples\" \"Examples\"" + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = "doxygen.error" + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = "../src/" "./" + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = "../src/matrix/camlapack/" "../src/matrix/camblas/" + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = ../src/test/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = images/ + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non empty doxygen will try to run +# the html help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = YES + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, +# or Internet explorer 4.0+). Note that for large projects the tree generation +# can take a very long time. In such cases it is better to disable this feature. +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = amsmath + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = jpg + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 800 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 120 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/doc/html/AstroToolbox_8h-source.html b/doc/html/AstroToolbox_8h-source.html new file mode 100644 index 0000000..49612ed --- /dev/null +++ b/doc/html/AstroToolbox_8h-source.html @@ -0,0 +1,103 @@ + + +AstroToolbox.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

AstroToolbox.h

Go to the documentation of this file.
00001 #ifndef ASTROTOOLBOX_H
+00002 #define ASTROTOOLBOX_H
+00003 
+00004 #include "cmatrix"
+00005 #include "math.h"
+00006 
+00007 using namespace std;
+00008 using namespace techsoft;
+00009 typedef matrix<double> Matrix;
+00010 
+00011 
+00012 
+00013 
+00014 inline Matrix eye(int rowcolumns)
+00015 {
+00016         Matrix eyeOutput(rowcolumns,rowcolumns,0.0);
+00017         eyeOutput.diag() = 1.0;
+00018         return eyeOutput;
+00019 }
+00020 
+00021 inline Matrix skew(Matrix input)
+00022 {
+00023         Matrix R(3,3,0.0);
+00024         R(0,1) = -input(2,0);
+00025         R(0,2) = input(1,0);
+00026         R(1,0) = input(2,0);
+00027         R(1,2) = -input(0,0);
+00028         R(2,0) = -input(1,0);
+00029         R(2,1) = input(0,0);
+00030         
+00031         return R;
+00032 }
+00033 
+00034 
+00035 inline Matrix Roi(double Om,double inc,double u)
+00036 {       //  function R = Roi(Om,inc,u)
+00037         //  returns the rotation matrix from inertial to
+00038         //  orbital frame, defined by
+00039         //    Om  = right ascension of the ascending node
+00040         //    inc = inclination         
+00041         //    u   = argument of latitude
+00042 
+00043         double sO = sin(Om);  double cO = cos(Om);
+00044         double si = sin(inc); double ci = cos(inc);
+00045         double su = sin(u);   double cu = cos(u);
+00046         Matrix R(3,3,1.0);
+00047                 R(0,0) = -su*cO-cu*ci*sO;
+00048                 R(0,1) = -su*sO+cu*ci*cO;
+00049                 R(0,2) = cu*si;
+00050                 R(1,0) = -si*sO;
+00051                 R(1,1) = si*cO;
+00052                 R(1,2) = -ci;
+00053                 R(2,0) = -cu*cO+su*ci*sO;
+00054                 R(2,1) = -cu*sO-su*ci*cO;
+00055                 R(2,2) = -su*si;
+00056         return R;
+00057 }
+00058 
+00059 inline Matrix q2R(Matrix q14)
+00060 {
+00061         q14 /= q14.norm2((Vector));
+00062         Matrix q4(1,1); q4 = q14(3,0);
+00063         double q4_v = q14(3,0);
+00064         Matrix q(3,1);  q = q14[mslice(0,0,3,1)];
+00065 
+00066         Matrix temp_m(3,3); temp_m = (pow(q4,2) - (~q) * q);
+00067         double temp_v = temp_m(0,0);
+00068         Matrix R(3,3); R = temp_v * eye(3) + 2.0 * q * (~q) - 2.0 * q4_v * skew(q);
+00069         return R;
+00070 }
+00071 
+00072 inline Matrix R2q(Matrix R)
+00073 {       //  q = R2q(R)
+00074         //      R is a rotation matrix
+00075         //      q is a quaternion (4 x 1) with q(1:3) the vector part
+00076         
+00077         double q4 = 0.5 * ::sqrt(1 + R.trace());
+00078         Matrix q(4,1,0.0);
+00079         q(0,0) = R(1,2)-R(2,1);
+00080         q(1,0) = R(2,0)-R(0,2);
+00081         q(2,0) = R(0,1)-R(1,0);
+00082         q /= (4 * q4);
+00083         q(3,0) = q4;
+00084         
+00085         q /= q.norm2((Vector));   // make sure it's unit length
+00086         return q;
+00087 }
+00088 
+00089 #endif
+

Generated on Thu Feb 27 13:46:15 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/AstroToolbox_8h.html b/doc/html/AstroToolbox_8h.html new file mode 100644 index 0000000..03bae79 --- /dev/null +++ b/doc/html/AstroToolbox_8h.html @@ -0,0 +1,222 @@ + + +AstroToolbox.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

AstroToolbox.h File Reference

#include "cmatrix"
+#include "math.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + +

Namespaces

namespace  std
namespace  techsoft

Typedefs

typedef matrix< double > Matrix

Functions

Matrix eye (int rowcolumns)
Matrix skew (Matrix input)
Matrix Roi (double Om, double inc, double u)
Matrix q2R (Matrix q14)
Matrix R2q (Matrix R)
+


Typedef Documentation

+

+ + + + +
+ + +
typedef matrix<double> Matrix +
+
+ + + + + +
+   + + +

+

+


Function Documentation

+

+ + + + +
+ + + + + + + + + + +
Matrix eye int   _rowColumns [inline]
+
+ + + + + +
+   + + +

+Creates an square identity matrix of specified size.

Parameters:
+ + +
_rowColumns  +Number of rows and columns to size matrix (will be a square matrix).
+
Todo:
+ Implement eye as part of Vector or CAMdoubleVector class
+

+ + + + +
+ + + + + + + + + + +
Matrix q2R Matrix   q14 [inline]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
Matrix R2q Matrix   R [inline]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrix Roi double   Om,
double   inc,
double   u
[inline]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
Matrix skew Matrix   input [inline]
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Attitude_8h-source.html b/doc/html/Attitude_8h-source.html new file mode 100644 index 0000000..bef1276 --- /dev/null +++ b/doc/html/Attitude_8h-source.html @@ -0,0 +1,79 @@ + + +Attitude.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Attitude.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00012 
+00013 
+00014 
+00016 enum AttitudeFrame{NO_FRAME = -1, BODY_ORBITAL = 1, BODY_INERTIAL = 2, BODY_ORBITAL_LINEAR = 3, BODY_INERTIAL_LINEAR = 4};
+00017 
+00022 class Attitude
+00023 {
+00026     Attitude();
+00027     
+00029     /* @defgroup AttitudeKinematics Attitude Kinematics
+00030     *   @ingroup DynamicsToolbox
+00031     *  \brief Attitude kinematics inspectors and mutators
+00032     *  @{
+00033         */
+00034 public:
+00035     // Inspectors
+00043     Rotation GetAttitude(AttitudeFrame _Frame = m_Frame);
+00044 
+00049     AttitudeFrame GetFrame();
+00050 
+00051     // Mutators
+00059     void SetFrame(AttitudeFrame _Frame);
+00060 
+00067     void SetAttitude(const Rotation &_Attitude, AttitudeFrame _Frame = NO_FRAME); 
+00068 
+00069 private:
+00070     AttitudeFrame m_Frame; 
+00071     Rotation m_Attitude; // end of AttitudeKinematics
+00073 
+00075     /* @defgroup AttitudeDynamics rigid body Attitude Dynamics
+00076         *   @ingroup DynamicsToolbox
+00077         *  \brief rigid body attitude dynamics inspectors and mutators
+00078         *  @{
+00079             */
+00080 public:
+00081     // Inspectors
+00086     Vector GetAngularVelocity();
+00087 
+00092     Vector GetAngularAcceleration();
+00093 
+00094     // Mutators
+00100     void SetAngularVelocity(const Vector &_AngularVelocity);
+00101 
+00107     void SetAngularAcceleration(const Vector &_AngularAcceleration);
+00108 
+00109 private:
+00110     Matrix m_AngularVelocity;
+00111     Matrix m_AngularAcceleration;
+00112  // end of AttitudeDynamics
+00114 
+00115 };
+00116 
+00117 /*****************************************************************************
+00118 *       $Log: Attitude_8h-source.html,v $
+00118 *       Revision 1.1.1.1  2003/02/27 18:55:52  nilspace
+00118 *       Moved the repository to its correct location.
+00118 *
+00119 *       Revision 1.1  2003/02/27 18:37:26  nilspace
+00120 *       Initial submission of Attitude class implementation.
+00121 *       
+00122 *
+00123 ******************************************************************************/
+

Generated on Thu Feb 27 13:46:15 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Attitude_8h.html b/doc/html/Attitude_8h.html new file mode 100644 index 0000000..1f9ed39 --- /dev/null +++ b/doc/html/Attitude_8h.html @@ -0,0 +1,88 @@ + + +Attitude.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Attitude.h File Reference

Interface to the Attitude class. +More... +

+ +

+Go to the source code of this file. + + + + + + +

Compounds

class  Attitude
 Class encapsulating the rotational attitude of a rigid body frame with respect to another frame. The Attitude class allows for the attitude to be stored, retrieved, history logged,. More...


Enumerations

enum  AttitudeFrame {
+  NO_FRAME = -1, +BODY_ORBITAL = 1, +BODY_INERTIAL = 2, +BODY_ORBITAL_LINEAR = 3, +
+  BODY_INERTIAL_LINEAR = 4 +
+ }
+


Detailed Description

+Interface to the Attitude class. +

+

Author:
+
Author:
+ nilspace
Version:
+
Revision:
+ 1.1
Date:
+
Date:
+ 2003/02/27 18:37:26
////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+Make Attitude derivable for diff't types of attitude representations (point-to, etc) +

+Implement export & import plug-ins (STK, matlab, excel...) +

+ Add Attitude history storage

+

+


Enumeration Type Documentation

+

+ + + + +
+ + +
enum AttitudeFrame +
+
+ + + + + +
+   + + +

+various types of attitude frames

Enumeration values:
+ + + + + + +
NO_FRAME  +
BODY_ORBITAL  +
BODY_INERTIAL  +
BODY_ORBITAL_LINEAR  +
BODY_INERTIAL_LINEAR  +
+
+
+


Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/CVS/Entries b/doc/html/CVS/Entries new file mode 100644 index 0000000..f636a38 --- /dev/null +++ b/doc/html/CVS/Entries @@ -0,0 +1,123 @@ +/AstroToolbox_8h-source.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/AstroToolbox_8h.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/Attitude_8h-source.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/Attitude_8h.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/Environment_8cpp.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/Environment_8h-source.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/Environment_8h.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/Matrix_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Matrix_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Matrix_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Orbit_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Orbit_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Orbit_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Plot_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Plot_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/RigidBody_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/RigidBody_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/RigidBody_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Rotation_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Rotation_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Rotation_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/RungeKutta_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/RungeKutta_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/SpacecraftTime_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/SpacecraftTime_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/SpacecraftToolboxConstants_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/SpacecraftToolboxConstants_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Spacecraft_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Spacecraft_8h-source.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Spacecraft_8h.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Spacecraft__Sim_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/TestRotation_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/Trigonometry_8h-source.html/1.1.1.1/Thu Feb 27 18:55:55 2003// +/Trigonometry_8h.html/1.1.1.1/Thu Feb 27 18:55:55 2003// +/annotated.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/bug.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/classAttitude-members.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/classAttitude.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/classCEnvironment-members.html/1.1.1.1/Thu Feb 27 18:55:52 2003// +/classCEnvironment.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classDirectionCosineMatrix-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classDirectionCosineMatrix.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classEnvironment-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classEnvironment.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classMatrix-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classMatrix.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classModifiedRodriguezParameters-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classModifiedRodriguezParameters.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classOrbit-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classOrbit.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classQuaternion-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classQuaternion.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classRigidBody-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classRigidBody.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classRotation-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classRotation.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classSpacecraft-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classSpacecraft.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classZeit-members.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/classZeit.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/doxygen.css/1.1.1.1/Thu Feb 27 18:55:53 2003// +/doxygen.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/files.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_0.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_1.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_10.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_11.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_12.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_13.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_14.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_15.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_16.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_17.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_18.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_19.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_2.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_20.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_21.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_3.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_4.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_5.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_6.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_7.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_8.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/form_9.png/1.1.1.1/Thu Feb 27 18:55:53 2003// +/formula.repository/1.1.1.1/Thu Feb 27 18:55:53 2003// +/functions.html/1.1.1.1/Thu Feb 27 18:55:53 2003// +/globals.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Attitude.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__AttitudeControl.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__AttitudeRepresentation.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Constructors.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__DCM.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__DCMOperators.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__DirectionCosineMatrix.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__EOM.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__FileAccess.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__History.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__MRP.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__MRPOperators.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__ModifiedRodriguezParameters.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Orbital.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__OrbitalControl.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Physical.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Propagators.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Quaternion.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__QuaternionOperators.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Rotation.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__RotationInspectors.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__RotationMutators.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__RotationOperators.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__SpacecraftFramework.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Trigonometry.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/group__Zeit.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/index.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/main_8cpp.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/modules.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/namespaces.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/namespacestd.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/namespacetechsoft.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/pages.html/1.1.1.1/Thu Feb 27 18:55:54 2003// +/todo.html/1.1.1.1/Thu Feb 27 18:55:55 2003// +D diff --git a/doc/html/CVS/Repository b/doc/html/CVS/Repository new file mode 100644 index 0000000..743d72d --- /dev/null +++ b/doc/html/CVS/Repository @@ -0,0 +1 @@ +spacecraft/doc/html diff --git a/doc/html/CVS/Root b/doc/html/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/doc/html/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/doc/html/Environment_8cpp.html b/doc/html/Environment_8cpp.html new file mode 100644 index 0000000..3105da5 --- /dev/null +++ b/doc/html/Environment_8cpp.html @@ -0,0 +1,18 @@ + + +Environment.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Environment.cpp File Reference

#include "Environment.h"
+ + +
+
Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Environment_8h-source.html b/doc/html/Environment_8h-source.html new file mode 100644 index 0000000..4787132 --- /dev/null +++ b/doc/html/Environment_8h-source.html @@ -0,0 +1,91 @@ + + +Environment.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Environment.h

Go to the documentation of this file.
00001 
+00002 
+00009 
+00011 
+00012 
+00013 #if !defined Environment_H
+00014 #define Environment_H
+00015 
+00016 #include "../Toolboxes/Matrix/Cmatrix"
+00017 #include "Spacecraft.h"
+00018 
+00035 class Environment  
+00036 {
+00037 public:
+00038         // Default Constructor
+00039         Environment();
+00040         // Constructor using pointer to Spacecraft in environment
+00041         Environment(const Spacecraft* _Satellite);
+00042         virtual ~Environment();
+00043 
+00044         // Sets the pointer to the spacecraft in the environment
+00045         void SetSpacecraft(Spacecraft* _Satellite);
+00046         
+00047         // Returns the summation of all the forces on the spacecraft due to the environment options
+00048         Matrix GetTorques();
+00049         // Returns the summation of all the torques on the spacecraft due to the environment options
+00050         Matrix GetForces();
+00051 
+00053         // OPTION SETTINGS
+00055         
+00056         // Activate/Deactivate option matrix of flags
+00057         void SetOptionsMatrix(Matrix _Options);
+00058         // Returns the current option settings
+00059         Matrix GetOptions();
+00060 
+00061         // Set a single option using macros to access option and TRUE to activate, FALSE to deactivate
+00062         void SetOption(int _Option, bool _OptionFlag);
+00063         // Returns a single option specified using option macros
+00064         bool GetOption(int _Option);
+00065 
+00067         // EXTERNAL VECTORS
+00069 
+00070         // Returns the local B-Field with respect to the body-frame
+00071         Matrix GetBField();
+00072         // Returns the vector to the center of the Earth with respect to the body-frame
+00073         Matrix EarthVector();
+00074         // Returns the vector to the center of the Sun with respect to the body-frame
+00075         Matrix SunVector();
+00076         // Returns the vector to the center of the Moon with respect to the body-frame
+00077         Matrix MoonVector();
+00078 
+00079 private:
+00080         // Option Flags: Access using macros and set to TRUE to activate an option
+00081         Matrix m_Option_Flags;
+00082 
+00083         // Pointer to the spacecraft in the environment being modelled
+00084         const Spacecraft* m_Satellite;
+00085 };
+00086 
+00087 // Macros for defining options location in 'Options' Matrix
+00088 #define OPTION_TORQUE_MAGNETIC                                  0
+00089 #define OPTION_TORQUE_GRAVITY                                   OPTION_TORQUE_MAGNETIC+1
+00090 #define OPTION_FORCE_GRAVITY                                    OPTION_TORQUE_GRAVITY+1
+00091 #define OPTION_FORCE_MOON_GRAVITY                               OPTION_FORCE_GRAVITY+1  
+00092 #define OPTION_FORCE_SUN_GRAVITY                                OPTION_FORCE_MOON_GRAVITY+1
+00093 #define OPTION_FORCE_J2                                                 OPTION_FORCE_SUN_GRAVITY+1
+00094 #define OPTION_FORCE_PRECESSION                                 OPTION_FORCE_J2+1
+00095 #define OPTION_FORCE_NUTATION                                   OPTION_FORCE_PRECESSION+1
+00096 #define OPTION_FORCE_ATMDRAG                                    OPTION_FORCE_NUTATION+1
+00097 #define OPTION_FORCE_RELATIVISTIC                               OPTION_FORCE_ATMDRAG+1
+00098 #define OPTION_FORCE_EARTH_TIDES                                OPTION_FORCE_RELATIVISTIC+1
+00099 #define OPTION_FORCE_EARTH_RADIATION_PRESSURE   OPTION_FORCE_EARTH_TIDES+1
+00100 #define OPTION_FORCE_SUN_RADIATION_PRESSURE             OPTION_FORCE_EARTH_RADIATION_PRESSURE+1
+00101 #define OPTION_FORCE_EMPIRICAL_FORCES                   OPTION_FORCE_SUN_RADIATION_PRESSURE+1
+00102 
+00103 
+00104 #endif // !defined(Environment_H)
+

Generated on Thu Feb 27 13:46:16 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Environment_8h.html b/doc/html/Environment_8h.html new file mode 100644 index 0000000..b1690a3 --- /dev/null +++ b/doc/html/Environment_8h.html @@ -0,0 +1,359 @@ + + +Environment.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Environment.h File Reference

Encapsulation of various environmental effects for modelling spacecraft motion and attitude dynamics. +More... +

+#include "../Toolboxes/Matrix/Cmatrix"
+#include "Spacecraft.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + + +

Compounds

class  Environment

Defines

#define OPTION_TORQUE_MAGNETIC   0
#define OPTION_TORQUE_GRAVITY   OPTION_TORQUE_MAGNETIC+1
#define OPTION_FORCE_GRAVITY   OPTION_TORQUE_GRAVITY+1
#define OPTION_FORCE_MOON_GRAVITY   OPTION_FORCE_GRAVITY+1
#define OPTION_FORCE_SUN_GRAVITY   OPTION_FORCE_MOON_GRAVITY+1
#define OPTION_FORCE_J2   OPTION_FORCE_SUN_GRAVITY+1
#define OPTION_FORCE_PRECESSION   OPTION_FORCE_J2+1
#define OPTION_FORCE_NUTATION   OPTION_FORCE_PRECESSION+1
#define OPTION_FORCE_ATMDRAG   OPTION_FORCE_NUTATION+1
#define OPTION_FORCE_RELATIVISTIC   OPTION_FORCE_ATMDRAG+1
#define OPTION_FORCE_EARTH_TIDES   OPTION_FORCE_RELATIVISTIC+1
#define OPTION_FORCE_EARTH_RADIATION_PRESSURE   OPTION_FORCE_EARTH_TIDES+1
#define OPTION_FORCE_SUN_RADIATION_PRESSURE   OPTION_FORCE_EARTH_RADIATION_PRESSURE+1
#define OPTION_FORCE_EMPIRICAL_FORCES   OPTION_FORCE_SUN_RADIATION_PRESSURE+1
+


Detailed Description

+Encapsulation of various environmental effects for modelling spacecraft motion and attitude dynamics. +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2001-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+ Fix to work w/ new rotation toolbox
+

+


Define Documentation

+

+ + + + +
+ + +
#define OPTION_FORCE_ATMDRAG   OPTION_FORCE_NUTATION+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_EARTH_RADIATION_PRESSURE   OPTION_FORCE_EARTH_TIDES+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_EARTH_TIDES   OPTION_FORCE_RELATIVISTIC+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_EMPIRICAL_FORCES   OPTION_FORCE_SUN_RADIATION_PRESSURE+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_GRAVITY   OPTION_TORQUE_GRAVITY+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_J2   OPTION_FORCE_SUN_GRAVITY+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_MOON_GRAVITY   OPTION_FORCE_GRAVITY+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_NUTATION   OPTION_FORCE_PRECESSION+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_PRECESSION   OPTION_FORCE_J2+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_RELATIVISTIC   OPTION_FORCE_ATMDRAG+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_SUN_GRAVITY   OPTION_FORCE_MOON_GRAVITY+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_FORCE_SUN_RADIATION_PRESSURE   OPTION_FORCE_EARTH_RADIATION_PRESSURE+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_TORQUE_GRAVITY   OPTION_TORQUE_MAGNETIC+1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define OPTION_TORQUE_MAGNETIC   0 +
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Matrix_8cpp.html b/doc/html/Matrix_8cpp.html new file mode 100644 index 0000000..98e1501 --- /dev/null +++ b/doc/html/Matrix_8cpp.html @@ -0,0 +1,18 @@ + + +Matrix.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Matrix.cpp File Reference

#include "Matrix.h"
+ + +
+
Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Matrix_8h-source.html b/doc/html/Matrix_8h-source.html new file mode 100644 index 0000000..4c67880 --- /dev/null +++ b/doc/html/Matrix_8h-source.html @@ -0,0 +1,93 @@ + + +Matrix.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Matrix.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00011 
+00012 
+00013 #ifndef MATRIX_H
+00014 #define MATRIX_H
+00015 
+00016 #include <iostream.h>
+00017 #include <cammva/cammva.h>
+00018 const int MatrixIndexBase = 1; 
+00019 const int VectorIndexBase = 1; 
+00020 const int MatrixRowsIndex = 1; 
+00021 const int MatrixColsIndex = 2; 
+00022 typedef CAMdoubleMatrix Matrix; 
+00023 typedef CAMdoubleVector Vector; 
+00029 inline Matrix eye(int _rowColumns)
+00030 {
+00031     Matrix eyeOutput(_rowColumns,_rowColumns);
+00032     eyeOutput.setToValue(0.0);
+00033     for(int ii = MatrixIndexBase;ii < _rowColumns + MatrixIndexBase; ++ii)
+00034         eyeOutput(ii,ii) = 1.0;
+00035     return eyeOutput;
+00036 }
+00037 
+00042 inline double trace(const Matrix &_inMatrix)
+00043 {
+00044     double Sum = 0;
+00045     for(int ii = MatrixIndexBase;ii < _inMatrix[MatrixRowsIndex].getIndexCount() + MatrixIndexBase; ++ii)
+00046         Sum += _inMatrix(ii,ii);
+00047     return Sum;
+00048 }
+00049 
+00055 inline double norm2(const Vector &_inVector)
+00056 {
+00057     double Sum = 0;
+00058     for(int ii = VectorIndexBase;ii < _inVector.getIndexCount() + VectorIndexBase; ++ii)
+00059         Sum += _inVector(ii) * _inVector(ii);
+00060     return sqrt(Sum);
+00061 }
+00062 
+00067 inline void normalize(Vector &_inVector)
+00068 {
+00069     _inVector /= norm2((Vector)_inVector);
+00070     return;
+00071 }
+00072 
+00078 inline double normInf(const Vector &_inVector)
+00079 {
+00080     return _inVector.maxAbs();
+00081 }
+00082 
+00097 inline Matrix skew(const Vector &_inVector)
+00098 {
+00099     Matrix Rout(3,3);
+00100     Rout.setToValue(0.0);
+00101     Rout(MatrixIndexBase+0,MatrixIndexBase+1) =
+00102         -_inVector(VectorIndexBase+2);
+00103     Rout(MatrixIndexBase+0,MatrixIndexBase+2) =
+00104         _inVector(VectorIndexBase+1);
+00105     Rout(MatrixIndexBase+1,MatrixIndexBase+0) =
+00106         _inVector(VectorIndexBase+2);
+00107     Rout(MatrixIndexBase+1,MatrixIndexBase+2) =
+00108         -_inVector(VectorIndexBase+0);
+00109     Rout(MatrixIndexBase+2,MatrixIndexBase+0) =
+00110         -_inVector(VectorIndexBase+1);
+00111     Rout(MatrixIndexBase+2,MatrixIndexBase+1) =
+00112         _inVector(VectorIndexBase+0);
+00113     return Rout;
+00114 }
+00115 
+00122 inline Vector crossP(const Vector &_v1, const Vector &_v2)
+00123 {
+00124     return skew(_v1) * _v2;
+00125 }
+00126 
+00127 #endif
+00128 
+00129 
+

Generated on Thu Feb 27 13:46:16 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Matrix_8h.html b/doc/html/Matrix_8h.html new file mode 100644 index 0000000..25493c5 --- /dev/null +++ b/doc/html/Matrix_8h.html @@ -0,0 +1,444 @@ + + +Matrix.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Matrix.h File Reference

Wrapper of tvmet Matrix Library. +More... +

+#include <iostream.h>
+#include <cammva/cammva.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + + + +

Typedefs

typedef CAMdoubleMatrix Matrix
typedef CAMdoubleVector Vector

Functions

Matrix eye (int _rowColumns)
double trace (const Matrix &_inMatrix)
double norm2 (const Vector &_inVector)
void normalize (Vector &_inVector)
double normInf (const Vector &_inVector)
Matrix skew (const Vector &_inVector)
Vector crossP (const Vector &_v1, const Vector &_v2)

Variables

const int MatrixIndexBase = 1
const int VectorIndexBase = 1
const int MatrixRowsIndex = 1
const int MatrixColsIndex = 2
+


Detailed Description

+Wrapper of tvmet Matrix Library. +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+Add overloading of operators +

+ Reference cammva documentation

+

+


Typedef Documentation

+

+ + + + +
+ + +
typedef CAMdoubleMatrix Matrix +
+
+ + + + + +
+   + + +

+Value referring to the "rows" index

+

+ + + + +
+ + +
typedef CAMdoubleVector Vector +
+
+ + + + + +
+   + + +

+Encapsulation of CAMdoubleMatrix class

+


Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Vector crossP const Vector  _v1,
const Vector  _v2
[inline]
+
+ + + + + +
+   + + +

+Calculates the cross product of 2 vectors. Equation: /f$ v_3 = v_1 \cross v_2 = v_1/f$

Parameters:
+ + +
_inVector  +Vector to calculate the 2-norm of.
+
Returns :
+Cross product of 2 vectors.
Todo:
+ Implement crossP as part of Vector or CAMdoubleVector class
+

+ + + + +
+ + + + + + + + + + +
Matrix eye int   _rowColumns [inline]
+
+ + + + + +
+   + + +

+Creates an square identity matrix of specified size.

Parameters:
+ + +
_rowColumns  +Number of rows and columns to size matrix (will be a square matrix).
+
Todo:
+ Implement eye as part of Vector or CAMdoubleVector class
+

+ + + + +
+ + + + + + + + + + +
double norm2 const Vector  _inVector [inline]
+
+ + + + + +
+   + + +

+Calculates the 2-norm of the vector (square-root of the sum of the squares).

Todo:
+Implement norm2 as part of Vector or CAMdoubleVector class
Parameters:
+ + +
_inVector  +Vector to calculate the 2-norm of.
+
Returns :
+Square-root of the sum of squares of elements in vector.
+

+ + + + +
+ + + + + + + + + + +
void normalize Vector  _inVector [inline]
+
+ + + + + +
+   + + +

+Normalizes a vector.

Parameters:
+ + +
_inVector  +Vector to be normalized.
+
Todo:
+ Implement normalize as part of Vector or CAMdoubleVector class
+

+ + + + +
+ + + + + + + + + + +
double normInf const Vector  _inVector [inline]
+
+ + + + + +
+   + + +

+Calculates the Infinity-norm of the vector (largest value of the components).

Parameters:
+ + +
_inVector  +Vector to calculate the 2-norm of.
+
Returns :
+Absolute value of maximum component in vector.
Todo:
+ Implement normInf as part of Vector or CAMdoubleVector class
+

+ + + + +
+ + + + + + + + + + +
Matrix skew const Vector  _inVector [inline]
+
+ + + + + +
+   + + +

+Calculates the skew-symmetric matrix of a vector. Equation: /f[ \bf{v^{\times}} = \begin{bmatrix} 0 & -v_3 & v_2\ v_3 & 0 & -v_1\ -v_2 & v_1 & 0 \end{bmatrix} /f]

Parameters:
+ + +
_inVector  +Vector to calculate the skew-symmetric matrix of.
+
Returns :
+Skew-symmetric matrix (3x3).
Todo:
+ Implement skew as part of Vector or CAMdoubleVector class
+

+ + + + +
+ + + + + + + + + + +
double trace const Matrix  _inMatrix [inline]
+
+ + + + + +
+   + + +

+Calculates the trace of matrix (sum of elements along diagonal).

Parameters:
+ + +
_inMatrix  +Matrix to have trace calculated.
+
Todo:
+ Implement trace as part of Vector or CAMdoubleVector class
+


Variable Documentation

+

+ + + + +
+ + +
const int MatrixColsIndex = 2 +
+
+ + + + + +
+   + + +

+Value referring to the "rows" index

+

+ + + + +
+ + +
const int MatrixIndexBase = 1 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
const int MatrixRowsIndex = 1 +
+
+ + + + + +
+   + + +

+Beginning index of Vector class

+

+ + + + +
+ + +
const int VectorIndexBase = 1 +
+
+ + + + + +
+   + + +

+Beginning index of Matrix class

+


Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Orbit_8cpp.html b/doc/html/Orbit_8cpp.html new file mode 100644 index 0000000..d125129 --- /dev/null +++ b/doc/html/Orbit_8cpp.html @@ -0,0 +1,19 @@ + + +Orbit.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Orbit.cpp File Reference

#include "stdafx.h"
+#include "Orbit.h"
+ + +
+
Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Orbit_8h-source.html b/doc/html/Orbit_8h-source.html new file mode 100644 index 0000000..b3672f1 --- /dev/null +++ b/doc/html/Orbit_8h-source.html @@ -0,0 +1,78 @@ + + +Orbit.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Orbit.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00012 
+00013 
+00014 #ifndef ORBIT_H
+00015 #define ORBIT_H
+00016 #include <Matrix.h>
+00017 
+00019 
+00025 class Orbit  
+00026 {
+00027 public:
+00031     Orbit();
+00032     
+00036     virtual ~Orbit();
+00037 
+00042     void SetOrbitalElements(Matrix _orbitalElements);
+00043 
+00044     void SetPositionVelocity(Matrix _Position, Matrix _Velocity);
+00045 
+00046     Matrix GetOrbitalElements();
+00047     Matrix GetPositionVelocity();
+00048     void GetPositionVelocity(Matrix &_Position, Matrix &_Velocity);
+00049 
+00051 
+00056 public:
+00057         // Inspectors
+00063         Matrix GetPosition();
+00064 
+00070     Matrix GetVelocity();
+00071 
+00077     double GetOrbitalAngularVelocity();
+00078 
+00084     double GetInclination();
+00085 
+00086 
+00087     // Mutators
+00094     void SetPositionVelocity(Matrix _InertialPosition, Matrix _InertialVelocity);
+00095 
+00096 private: 
+00097         Matrix m_InertialPosition;
+00098     Matrix m_InertialVelocity;
+00099     double m_Inclination;
+00100     double m_OrbitalAngularVelocity;
+00101  // end of Orbital
+00104     /** @defgroup OrbitalControl Orbital Control
+00105         *   @ingroup SpacecraftFramework
+00106         *  Spacecraft orbital control inspectors and mutators
+00107         *  @{
+00108             */
+00109 public:
+00115         void SetControlForces(Matrix _ControlForces);
+00116 
+00117 private:
+00118         Matrix m_SpacecraftForces;
+00119  // end of OrbitalControl
+00121     
+00122 private:
+00123     Matrix m_Position;
+00124     Matrix m_Velocity;
+00125 };
+00126 
+00127 #endif // ORBIT_H
+

Generated on Thu Feb 27 13:46:16 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Orbit_8h.html b/doc/html/Orbit_8h.html new file mode 100644 index 0000000..fc6d0e0 --- /dev/null +++ b/doc/html/Orbit_8h.html @@ -0,0 +1,38 @@ + + +Orbit.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Orbit.h File Reference

interface for the Orbit class. +More... +

+#include <Matrix.h>
+ +

+Go to the source code of this file. + + + +

Compounds

class  Orbit
+


Detailed Description

+interface for the Orbit class. +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2001-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+Implement encapsulation of orbit parameters +

+Add functionality for setting & retrieving w/ different representations +

+ Fix to work w/ new matrix toolbox

+

+


Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Plot_8h-source.html b/doc/html/Plot_8h-source.html new file mode 100644 index 0000000..990bb78 --- /dev/null +++ b/doc/html/Plot_8h-source.html @@ -0,0 +1,37 @@ + + +Plot.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Plot.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00011 
+00012 
+00013 void plot()
+00014 {
+00015 FILE* pipeVar;
+00016     pipeVar = popen("gnuplot","w");
+00017     /* opens writeable one-way pipe to
+00018                     gnuplot. If not in path, errors
+00019      will occur. Return val of popen
+00020      will be NULL if error occurs.
+00021      see popen man page for details */
+00022     fprintf(pipeVar, "plot sin(x)\n"); /* sends command to gnuplot
+00023             Note: fprintf must be used,
+00024      cout won't work */
+00025     /* You can also send a variable containing the command instead of the
+00026         quoted string I show above, but it must be a char* string */
+00027     fflush(pipeVar); /* pipes are buffered, so flush buffer after you are
+00028         finished */
+00029     pclose(pipeVar); // close pipe when you are finished with your program
+00030 }
+

Generated on Thu Feb 27 13:46:16 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Plot_8h.html b/doc/html/Plot_8h.html new file mode 100644 index 0000000..414d526 --- /dev/null +++ b/doc/html/Plot_8h.html @@ -0,0 +1,64 @@ + + +Plot.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Plot.h File Reference

Interface to GNUPLOT (http://www.gnuplot.org). +More... +

+ +

+Go to the source code of this file. + + + +

Functions

void plot ()
+


Detailed Description

+Interface to GNUPLOT (http://www.gnuplot.org). +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2001-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+Implement functions for various methods of plotting +

+ Fix to work w/ new matrix toolbox

+

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
void plot  
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/RigidBody_8cpp.html b/doc/html/RigidBody_8cpp.html new file mode 100644 index 0000000..52879da --- /dev/null +++ b/doc/html/RigidBody_8cpp.html @@ -0,0 +1,64 @@ + + +RigidBody.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

RigidBody.cpp File Reference

Implementation of the Rigid Body class. +More... +

+#include "RigidBody.h"
+ + + + +

Functions

void SetMomentsInertia (const Matrix &_momentsInertia)
+


Detailed Description

+Implementation of the Rigid Body class. +

+

Author:
+
Author:
+ ajturner
Version:
+
Revision:
+ 1.1
Date:
+
Date:
+ 2003/02/19 14:00:00
//////////////////////////////////////////////////////////////////////////////////////////////// +

+


Function Documentation

+

+ + + + +
+ + + + + + + + + + +
void SetMomentsInertia const Matrix  _momentsInertia
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/RigidBody_8h-source.html b/doc/html/RigidBody_8h-source.html new file mode 100644 index 0000000..46b089e --- /dev/null +++ b/doc/html/RigidBody_8h-source.html @@ -0,0 +1,57 @@ + + +RigidBody.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

RigidBody.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00010 
+00011 
+00016 class RigidBody
+00017 {
+00018 public:
+00021     RigidBody();
+00022     
+00027     Matrix GetMomentsInertia();
+00028 
+00033     void SetMomentsInertia(const Matrix &_momentsInertia);
+00034 
+00039     Matrix GetAppliedTorques();
+00040 
+00045     Attitude* GetAttitude();
+00046 
+00055     void Propagate(double StartTime, double EndTime, int numSteps = 100);
+00056     
+00057 private:
+00058     Matrix m_MomentsInertia;
+00059     Attitude m_Attitude;
+00060 
+00062     /* @defgroup EOM Equations of Motion
+00063         *  The equations of motion (EOM) define the time dynamics of the rigid body.
+00064         *  @{
+00065             */
+00073     static Matrix EOM(double time, Matrix stateVariables, Matrix constantsInput);
+00074 
+00075 private:
+00076     Matrix (*FuncPtr)(double timeInput, Matrix stateInput, Matrix constantsInput);
+00077  // end of EOM    
+00079     
+00080 }
+00081 
+00082 /*****************************************************************************
+00083 *       $Log: RigidBody_8h-source.html,v $
+00083 *       Revision 1.1.1.1  2003/02/27 18:55:54  nilspace
+00083 *       Moved the repository to its correct location.
+00083 *
+00084 *
+00085 ******************************************************************************/
+

Generated on Thu Feb 27 13:46:16 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/RigidBody_8h.html b/doc/html/RigidBody_8h.html new file mode 100644 index 0000000..3c708e1 --- /dev/null +++ b/doc/html/RigidBody_8h.html @@ -0,0 +1,36 @@ + + +RigidBody.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

RigidBody.h File Reference

Interface definition to the Rigid Body class. +More... +

+ +

+Go to the source code of this file. + + + + +

Compounds

class  RigidBody
 Encapsulation of a rigid body simulation. The RigidBody class outlines an interface to the simulation of a rigid body, including rotation kinematics and dynamics. More...

+


Detailed Description

+Interface definition to the Rigid Body class. +

+

Author:
+
Author:
+ ajturner
Version:
+
Revision:
+ 1.1
Date:
+
Date:
+ 2003/02/19 14:00:00
//////////////////////////////////////////////////////////////////////////////////////////////// +

+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Rotation_8cpp.html b/doc/html/Rotation_8cpp.html new file mode 100644 index 0000000..b57907f --- /dev/null +++ b/doc/html/Rotation_8cpp.html @@ -0,0 +1,36 @@ + + +Rotation.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation.cpp File Reference

Implementation of Rotation Namespace Objects. Provides a set of functions to use Rotation matrices and their various representations. +More... +

+#include "Rotation.h"
+ + + + + + +

Functions

DirectionCosineMatrix R1 (const double &_Angle)
DirectionCosineMatrix R2 (const double &_Angle)
DirectionCosineMatrix R3 (const double &_Angle)
+


Detailed Description

+Implementation of Rotation Namespace Objects. Provides a set of functions to use Rotation matrices and their various representations. +

+

Author:
+Andrew Turner <ajturner@vt.edu> , Chris Hall <cdhall@vt.edu>
Version:
+0.1
Date:
+2001-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Bug:
+Matrix class doesn't currently work
Warning:
+
Todo:
+ Implement Gibbs vector representation
+

+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Rotation_8h-source.html b/doc/html/Rotation_8h-source.html new file mode 100644 index 0000000..2eb77fe --- /dev/null +++ b/doc/html/Rotation_8h-source.html @@ -0,0 +1,276 @@ + + +Rotation.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation.h

Go to the documentation of this file.
00001 
+00002 
+00011 
+00015 
+00016 
+00017 #ifndef ROTATION_H
+00018 #define ROTATION_H
+00019 
+00020 #include "Matrix.h"
+00021 
+00022 // Prototype definitions of classes in Rotation Toolbox
+00023 class Quaternion;
+00024 class DirectionCosineMatrix;
+00025 class ModifiedRodriguezParameters;
+00026 class Rotation;                 
+00027 
+00028 
+00030 const int QUATERNION_SIZE = 4;
+00032 const int MRP_SIZE = 3;
+00034 const int DCM_SIZE = 3;
+00035 
+00036 
+00038 
+00044 
+00045 
+00050 class DirectionCosineMatrix:public Matrix
+00051 {
+00052 public:
+00057     DirectionCosineMatrix();
+00058     
+00062     virtual ~DirectionCosineMatrix() {}
+00063 
+00068     DirectionCosineMatrix(const DirectionCosineMatrix &_DCM);
+00069 
+00074     DirectionCosineMatrix(const Matrix &_DCM);
+00075 
+00081     DirectionCosineMatrix(const Vector &_EulerAngles, const int &_Sequence);
+00082 
+00088     DirectionCosineMatrix(const Vector &_EulerAxis, const double &_EulerAngle);
+00089 
+00097     DirectionCosineMatrix(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence);
+00098 
+00103     DirectionCosineMatrix(const ModifiedRodriguezParameters &_MRP);
+00104 
+00110     DirectionCosineMatrix(const Quaternion &_quat);
+00111     
+00116     void Set(const DirectionCosineMatrix &_DCM);
+00117 
+00123     void Set(const Vector &_EulerAngles, const int &_Sequence);
+00124 
+00132     void Set(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence);
+00133 
+00139     void Set(const Vector &_EulerAxis, const double &_EulerAngle);
+00140 
+00145     void Set(const ModifiedRodriguezParameters &_MRP);
+00146     
+00152     void Set(const Quaternion &_qIn);
+00153 
+00159     Vector GetEulerAngles(const int &_Sequence) const;
+00160 
+00166     void GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle);
+00167     
+00172     ModifiedRodriguezParameters GetMRP() const;
+00173     
+00178     Quaternion GetQuaternion() const;
+00179     
+00184     DirectionCosineMatrix operator+ (const DirectionCosineMatrix& _DCM2) const;
+00185 
+00190     DirectionCosineMatrix operator- (const DirectionCosineMatrix& _DCM2) const;
+00191 
+00196     inline DirectionCosineMatrix operator* (const DirectionCosineMatrix& _DCM2) const {return (*this) * _DCM2;}
+00197 
+00202     inline DirectionCosineMatrix operator~ () {return operator~();};
+00203     
+00204 };
+00205 
+00210 DirectionCosineMatrix R1(const double &_Angle);
+00211 
+00216 DirectionCosineMatrix R2(const double &_Angle);
+00217 
+00222 DirectionCosineMatrix R3(const double &_Angle); // end of DirectionCosineMatrix
+00224 
+00226 
+00231 class ModifiedRodriguezParameters:public Vector
+00232 {
+00233 public:
+00238     ModifiedRodriguezParameters();
+00239 
+00244     ModifiedRodriguezParameters(const ModifiedRodriguezParameters &_MRP);
+00245     
+00252     ModifiedRodriguezParameters(double _s1, double _s2, double _s3);
+00253     
+00258     ModifiedRodriguezParameters(const Vector &_sVector);
+00259 
+00264     ModifiedRodriguezParameters(const DirectionCosineMatrix &_DCM);
+00265 
+00271     ModifiedRodriguezParameters(const Vector &_Angles, const int &_Sequence);
+00272 
+00278     ModifiedRodriguezParameters(const Vector &_EulerAxis, const double &_EulerAngle);
+00279     
+00284     ModifiedRodriguezParameters(const Quaternion &_qIN);
+00285 
+00289     void Set(const ModifiedRodriguezParameters &_MRP);
+00290     
+00297     void Set(double _s1, double _s2, double _s3);
+00298 
+00303     void Set(const Vector &_sVector);
+00304     
+00309     void Set(const DirectionCosineMatrix &_DCM);
+00310 
+00316     void Set(const Vector &_EulerAngles, const int &_Sequence);
+00317 
+00325     void Set(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence);
+00326 
+00332     void Set(const Vector &_EulerAxis, const double &_EulerAngle);
+00333     
+00338     void Set(const Quaternion &_qIN);
+00339 
+00344     DirectionCosineMatrix GetDCM() const;
+00345 
+00351     Vector GetEulerAngles(int _Sequence) const;
+00352 
+00358     void GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle) const;
+00359     
+00364     Quaternion GetQuaternion() const;
+00365     
+00371     void Switch(int _SwitchThreshold = 1);
+00372 
+00378     void AutoSwitch(bool _SwitchBoolean = true);
+00379 
+00384     ModifiedRodriguezParameters ShadowSet();
+00385 
+00390     ModifiedRodriguezParameters operator+ (const ModifiedRodriguezParameters &_MRP2) const;
+00391 
+00396     ModifiedRodriguezParameters operator- (const ModifiedRodriguezParameters& _MRP2) const; // end of MRPOperators
+00398 private:
+00402     bool m_AutoSwitch;
+00403 }; // end of ModifiedRodriguezParameters
+00405 
+00407 
+00421 class Quaternion:public Vector
+00422 {
+00423 public:
+00428     Quaternion();
+00429 
+00438     Quaternion(double _q1, double _q2, double _q3, double _q4);
+00439 
+00445     Quaternion(const Vector &_qVector);
+00446 
+00452     Quaternion(const DirectionCosineMatrix &_DCM);
+00453 
+00459     Quaternion(const Vector &_EulerAngles, const int &_Sequence);
+00460 
+00466     Quaternion(const Vector &_EulerAxis, const double &_EulerAngle);
+00467 
+00472     Quaternion(const ModifiedRodriguezParameters &_MRP);
+00473 
+00477     void Normalize();
+00478 
+00483     void Set(const Quaternion &_qIn);
+00484 
+00492     void Set(double _q1, double _q2, double _q3, double _q4);
+00493 
+00498     void Set(const Vector &_qVector);
+00499 
+00504     void Set(const DirectionCosineMatrix &_DCM);
+00505 
+00511     void Set(const Vector &_EulerAngles, const int &_Sequence);
+00512 
+00518     void Set(const Vector &_EulerAxis, const double &_EulerAngle);
+00519 
+00524     void Set(const ModifiedRodriguezParameters &_MRP);
+00525 
+00531     DirectionCosineMatrix GetDCM() const;
+00532 
+00538     Vector GetEulerAngles(const int &_Sequence) const;
+00539 
+00545     void GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle);
+00546 
+00552     ModifiedRodriguezParameters GetMRP() const;
+00553 
+00555 
+00559     Quaternion operator+ (const Quaternion& _quat2) const;
+00560 
+00565     Quaternion operator- (const Quaternion& _quat2) const;
+00566 
+00567 private:
+00568 
+00569 }; // end of Quaternion
+00571 
+00573 
+00577 class Rotation
+00578 {
+00579 public:
+00580     // RotationConstructors
+00585     Rotation();
+00586 
+00591     Rotation(const Matrix &_inMatrix);
+00592 
+00597     Rotation(const DirectionCosineMatrix &_DCM);
+00598 
+00604     Rotation(const Vector &_Angles, const int &_Sequence);
+00605 
+00613     Rotation(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence);
+00614 
+00615 
+00621     Rotation(const Vector &_Axis, const double &_Angle);
+00622 
+00627     Rotation(const ModifiedRodriguezParameters &_MRP);
+00628 
+00633     Rotation(const Quaternion &_quat);
+00634 
+00638     ~Rotation();
+00639 
+00640     // end of RotationConstructors
+00641 
+00642     // RotationMutators
+00647     void Set(const Matrix &_inMatrix);
+00648 
+00653     void Set(const DirectionCosineMatrix &_DCM);
+00654 
+00660     void Set(const Vector &_Angles, const int &_Sequence);
+00661 
+00669     void Set(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence);
+00670 
+00676     void Set(const Vector &_Axis, const double &_Angle);
+00677 
+00682     void Set(const ModifiedRodriguezParameters &_MRP);
+00683 
+00688     void Set(const Quaternion &_quat);
+00689 
+00690     // end of RotationMutators
+00691 
+00692     // RotationInspectors
+00697     DirectionCosineMatrix GetDCM() const;
+00698 
+00704     Vector GetEulerAngles(const int& _Sequence);
+00705 
+00711     void GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle) const;
+00712 
+00717     ModifiedRodriguezParameters GetMRP() const;
+00718 
+00719 
+00724     Quaternion GetQuaternion() const;
+00725 
+00726     // end of RotationInspectors
+00727 
+00728     // RotationOperators
+00733     Rotation Rotation::operator* (const Rotation& _rot2) const;
+00734 
+00739     Rotation Rotation::operator~ () const;
+00740 
+00745     Rotation Rotation::operator+ (const Rotation& _rot2) const;
+00746 
+00751     Rotation Rotation::operator- (const Rotation& _rot2) const;
+00752     // end of RotationOperators
+00753 
+00754 private:
+00756         Quaternion m_quaternion;
+00757 
+00758 }; // end of Rotation // end of AttitudeRepresentation
+00761 #endif 
+

Generated on Thu Feb 27 13:46:17 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Rotation_8h.html b/doc/html/Rotation_8h.html new file mode 100644 index 0000000..0c7854b --- /dev/null +++ b/doc/html/Rotation_8h.html @@ -0,0 +1,115 @@ + + +Rotation.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation.h File Reference

Rotation toolkit. Provides a set of functions to use Rotation matrices and their various representations. +More... +

+#include "Matrix.h"
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + +

Compounds

class  DirectionCosineMatrix
class  ModifiedRodriguezParameters
class  Quaternion
class  Rotation

Functions

DirectionCosineMatrix R1 (const double &_Angle)
DirectionCosineMatrix R2 (const double &_Angle)
DirectionCosineMatrix R3 (const double &_Angle)

Variables

const int QUATERNION_SIZE = 4
const int MRP_SIZE = 3
const int DCM_SIZE = 3
+


Detailed Description

+Rotation toolkit. Provides a set of functions to use Rotation matrices and their various representations. +

+

Author:
+Andrew Turner <ajturner@vt.edu> , Chris Hall <cdhall@vt.edu>
Version:
+0.1
Date:
+2001-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Warning:
+
Todo:
+Implement Gibbs vector representation +

+ Wrap Rotation library in a namespace

+

+


Variable Documentation

+

+ + + + +
+ + +
const int DCM_SIZE = 3 +
+
+ + + + + +
+   + + +

+Number of elements in a DCM row or column

+

+ + + + +
+ + +
const int MRP_SIZE = 3 +
+
+ + + + + +
+   + + +

+Number of elements in a MRP vector

+

+ + + + +
+ + +
const int QUATERNION_SIZE = 4 +
+
+ + + + + +
+   + + +

+Number of elements in a quaternion vector

+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/RungeKutta_8h-source.html b/doc/html/RungeKutta_8h-source.html new file mode 100644 index 0000000..513c200 --- /dev/null +++ b/doc/html/RungeKutta_8h-source.html @@ -0,0 +1,68 @@ + + +RungeKutta.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

RungeKutta.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00010 
+00011 
+00012 #ifndef RUNGEKUTTA_H
+00013 #define RUNGEKUTTA_H
+00014 
+00015 #include <Matrix.h>
+00016 
+00017 
+00042 inline Matrix RungeKuttaSolve(Matrix (*odeFunc)(double timeInput, Vector stateInput, Matrix constantsInput), const Vector &_initialConditions, const Matrix &_constants, const double &_timeInitial, const double &_timeFinal, const int &_numSteps)
+00043 {
+00044         
+00045         double h = (_timeFinal - _timeInitial) / _numSteps;
+00046         double t = _timeInitial;
+00047         int numEqs = _initialConditions.getIndexCount();
+00048         Vector inputs(numEqs); inputs = _initialConditions;
+00049         Vector K1(numEqs);
+00050         Vector K2(numEqs);
+00051         Vector K3(numEqs);
+00052         Vector K4(numEqs);
+00053 
+00054         Matrix output(_numSteps + 1, numEqs + 1);
+00055 
+00056         output(0,0) = _timeInitial;
+00057         output(0,_(1,numEqs)) = ~_initialConditions;
+00058 
+00059         Vector temp(numEqs);
+00060         for (int ii = 1; ii <= _numSteps; ++ii)
+00061         {
+00062             K1 = h * odeFunc(t, inputs, _constants);
+00063             temp = inputs + K1 / 2.0;
+00064             K2 = h * odeFunc(t + h/2, temp, _constants);
+00065             temp = inputs + K2 / 2.0;
+00066             K3 = h * odeFunc(t + h/2, temp, _constants);
+00067             temp = inputs + K3;
+00068             K4 = h * odeFunc(t + h, temp, _constants);
+00069             for (int jj = 0; jj < numEqs; ++jj)
+00070             {
+00071                 inputs(jj) += (K1(jj)
+00072                                  + 2.0 * K2(jj)
+00073                                  + 2.0 * K3(jj)
+00074                                  + K4(jj)) / 6.0;                       
+00075             }
+00076             t = _timeInitial + ii * h;
+00077             output(ii,0) = t;
+00078             output(ii,_(1,numEqs)) = ~inputs;   
+00079         }
+00080         return output;
+00081 }
+00082 
+00083 
+00084 #endif RungeKutta
+

Generated on Thu Feb 27 13:46:17 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/RungeKutta_8h.html b/doc/html/RungeKutta_8h.html new file mode 100644 index 0000000..b27ed45 --- /dev/null +++ b/doc/html/RungeKutta_8h.html @@ -0,0 +1,121 @@ + + +RungeKutta.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

RungeKutta.h File Reference

Runge-Kutta integrator. +More... +

+#include <Matrix.h>
+ +

+Go to the source code of this file. + + + +

Functions

Matrix RungeKuttaSolve (Matrix(*odeFunc)(double timeInput, Vector stateInput, Matrix constantsInput), const Vector &_initialConditions, const Matrix &_constants, const double &_timeInitial, const double &_timeFinal, const int &_numSteps)
+


Detailed Description

+Runge-Kutta integrator. +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2002-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+ Add test cases
+

+


Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Matrix RungeKuttaSolve Matrix(*   odeFunc)(double timeInput, Vector stateInput, Matrix constantsInput),
const Vector  _initialConditions,
const Matrix  _constants,
const double &   _timeInitial,
const double &   _timeFinal,
const int &   _numSteps
[inline]
+
+ + + + + +
+   + + +

+Integrate an equation of the form + using the Runge-Kutta integration method. \detail The Runge-Kutta integrator uses a right-hand side equation, + to compute the integration of the function over the specified time interval, given initial conditions, constants of integration, and number of steps desired (since this is a fixed step integrator).

Parameters:
+ + + + + + + + + + +
odeFunc  +Pointer to the right-hand side (RHS) equation
timeInput  +time of current step to RHS file function
stateInput  +vector of state inputs at current step to RHS file function
constantsInput  +vector of constants that are not integrated and passed to the RHS function
_initialConditions  +vector of initial conditions of the state
_constants  +matrix of constants that should be passed to the RHS function
_timeInitial  +initial time of integration
_timeFinal  +final time of integration
_numSteps  +number of steps to integrate over (therefore timeStep = _timeFinal - _timeInitial / _numSteps)
+
Returns :
+matrix of integrated state outputs from the initial to final times. Format: /f[ \begin{bmatrix} t_0 & x_{1,0} & x_{2,0} & ...\ t_1 & x_{1,1} & x_{2,1} & ...\ t_2 & x_{1,2} & x_{2,2} & ...\ . & . & . & . \ t_final & x_{1,f} & x_{2,f} & ... \end{bmatrix} /f] where /f$t_T/f$ is the time at step T, and /f$x_{i,T}/f$ is the state value of element i, at time step T.
+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/SpacecraftTime_8h-source.html b/doc/html/SpacecraftTime_8h-source.html new file mode 100644 index 0000000..34939c6 --- /dev/null +++ b/doc/html/SpacecraftTime_8h-source.html @@ -0,0 +1,46 @@ + + +SpacecraftTime.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

SpacecraftTime.h

Go to the documentation of this file.
00001 /*
+00002  *  SpacecraftTime.h
+00003  *  SpacecraftToolbox
+00004  *
+00005  *  Created by Andrew Turner on Mon Jan 27 2003.
+00006  *  Copyright (c) 2003 Step Through the Looking-Glass. All rights reserved.
+00007  *
+00008  */
+00009 #ifndef ZEIT_H
+00010 #define ZEIT_H
+00011 
+00012 
+00017 class Zeit
+00018 {
+00019 public:
+00020     Zeit();
+00021 
+00025     void Set();
+00026 
+00027     SetUT(matrix UT);
+00028     Matrix GetUT();
+00029 
+00030     void SetMJD(Matrix _MJD);
+00031     Matrix GetMJD();
+00032     
+00033 private:
+00034     UInt m_MJD; \\ MJD Time
+00035     UInt m_
+00036 }
+00037  // end of Zeit
+00039 #endif 
+00040 
+

Generated on Thu Feb 27 13:46:17 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/SpacecraftTime_8h.html b/doc/html/SpacecraftTime_8h.html new file mode 100644 index 0000000..55ebdb4 --- /dev/null +++ b/doc/html/SpacecraftTime_8h.html @@ -0,0 +1,21 @@ + + +SpacecraftTime.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

SpacecraftTime.h File Reference

+

+Go to the source code of this file. + + + +

Compounds

class  Zeit
+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/SpacecraftToolboxConstants_8h-source.html b/doc/html/SpacecraftToolboxConstants_8h-source.html new file mode 100644 index 0000000..8368dae --- /dev/null +++ b/doc/html/SpacecraftToolboxConstants_8h-source.html @@ -0,0 +1,27 @@ + + +SpacecraftToolboxConstants.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

SpacecraftToolboxConstants.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00012 
+00013 
+00014 #include "Trigonometry.h"
+00015 
+00016 
+00018 const double EARTH_RADIUS = 6.37 * powf(10,6);
+00020 const double GRAVITATIONAL_CONSTANT = 6.669 * powf(10,-11); 
+00022 const double EARTH_MASS = 5.98 * powf(10,24);
+00024 const double deg2rad = (float)PI / 180;
+00025 
+

Generated on Thu Feb 27 13:46:17 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/SpacecraftToolboxConstants_8h.html b/doc/html/SpacecraftToolboxConstants_8h.html new file mode 100644 index 0000000..a7db3ca --- /dev/null +++ b/doc/html/SpacecraftToolboxConstants_8h.html @@ -0,0 +1,128 @@ + + +SpacecraftToolboxConstants.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

SpacecraftToolboxConstants.h File Reference

Collection of typical constants used for spacecraft analysis and operations. +More... +

+#include "Trigonometry.h"
+ +

+Go to the source code of this file. + + + + + + +

Variables

const double EARTH_RADIUS = 6.37 * powf(10,6)
const double GRAVITATIONAL_CONSTANT = 6.669 * powf(10,-11)
const double EARTH_MASS = 5.98 * powf(10,24)
const double deg2rad = (float)PI / 180
+


Detailed Description

+Collection of typical constants used for spacecraft analysis and operations. +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2001-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Bug:
+Matrix class doesn't currently work
Warning:
+
Todo:
+ Implement Gibbs vector representation
+

+


Variable Documentation

+

+ + + + +
+ + +
const double deg2rad = (float)PI / 180 +
+
+ + + + + +
+   + + +

+Earth Radius [-]

+

+ + + + +
+ + +
const double EARTH_MASS = 5.98 * powf(10,24) +
+
+ + + + + +
+   + + +

+Earth Radius [kg]

+

+ + + + +
+ + +
const double EARTH_RADIUS = 6.37 * powf(10,6) +
+
+ + + + + +
+   + + +

+Earth Radius [m]

+

+ + + + +
+ + +
const double GRAVITATIONAL_CONSTANT = 6.669 * powf(10,-11) +
+
+ + + + + +
+   + + +

+Earth Radius [/f$m^3/kg-s^2/f$]

+


Generated on Thu Feb 27 13:46:20 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Spacecraft_8cpp.html b/doc/html/Spacecraft_8cpp.html new file mode 100644 index 0000000..32a59be --- /dev/null +++ b/doc/html/Spacecraft_8cpp.html @@ -0,0 +1,18 @@ + + +Spacecraft.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft.cpp File Reference

#include "Spacecraft.h"
+ + +
+
Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Spacecraft_8h-source.html b/doc/html/Spacecraft_8h-source.html new file mode 100644 index 0000000..90ef970 --- /dev/null +++ b/doc/html/Spacecraft_8h-source.html @@ -0,0 +1,126 @@ + + +Spacecraft.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft.h

Go to the documentation of this file.
00001 
+00002 
+00010 
+00012 
+00013 
+00015 
+00038 
+00039 
+00040 #ifndef SPACECRAFT_H
+00041 #define SPACECRAFT_H
+00042 
+00043 #include "../Toolboxes/RungeKutta.h"
+00044 #include "../Toolboxes/AstroToolbox.h"
+00045 #include "../Toolboxes/Rotation/Rotation.h"
+00046 
+00047 #include "../Toolboxes/Cmatrix"
+00048 #include <string> 
+00049 #include <fstream>
+00050 #include "..\TOOLBOXES\ROTATION\Rotation.h"     // Added by ClassView
+00051 using namespace std;
+00052 using namespace techsoft;
+00053 
+00054 typedef matrix<double> Matrix;
+00055 
+00056 #define MAX_TORQUE 0.9  
+00057 #define MIN_TORQUE -0.9
+00058 
+00060 
+00064 class Spacecraft  
+00065 {
+00066 public:
+00068 
+00077     Spacecraft();
+00078     
+00088     Spacecraft(Quaternion AttitudeQuaternion, Matrix AngularVelocity, Matrix AngularAcceleration, Matrix InertialPosition, Matrix InertialVelocity);
+00089 
+00093     virtual ~Spacecraft(); // end of Constructors
+00095     
+00097 
+00110         void Propagate(double StartTime, double EndTime, int numSteps = 100); // end of Propagators
+00112         
+00114 
+00127         static Matrix EOM_bi(double time, Matrix stateVariables, Matrix constantsInput);
+00128 
+00137         static Matrix EOM_bo(double time, Matrix stateVariables, Matrix constantsInput);
+00138 
+00147         static Matrix EOM_bo_Linear(double time, Matrix stateVariables, Matrix constantsInput);
+00148 
+00149 private:
+00150         Matrix (*FuncPtr)(double timeInput, Matrix stateInput, Matrix constantsInput);
+00151  // end of EOM
+00153 
+00154         
+00155 
+00157 
+00162 public:
+00168         Matrix GetMomentsInertia();
+00169 
+00175         Matrix GetSpacecraftTorques();
+00176 
+00182         void SetMomentsInertia(Matrix _momentsInertia);
+00183 
+00184 private:
+00185         Matrix m_MomentsInertia;
+00186         double m_Altitude;
+00187  // end of Physical
+00190 /** @defgroup History History
+00191 *   @ingroup SpacecraftFramework
+00192 *  Spacecraft flight history 
+00193 *  @{
+00194 */
+00195         
+00196 public:
+00202         void SetNumHistorySteps(int _numSteps);
+00203 
+00208         void ResetFlightHistory();
+00209 
+00218         Matrix GetFlightHistory(double _beginTime = -1, double _endTime = -1, AttitudeFrame _Frame = NO_FRAME);
+00219 
+00220 
+00227         Matrix GetFlightHistory(AttitudeFrame _Frame);
+00228 
+00236         Matrix GetControlHistory(double _beginTime = -1, double _endTime = -1);
+00237 
+00238 private: 
+00239         int m_HistoryStep;
+00240         Matrix m_FlightHistory;
+00241         Matrix m_ControlHistory;
+00242         void SetFlightHistory(Matrix _flightHistory);
+00243         void SetControlHistory(Matrix _flightHistory);
+00244  // end of Physical
+00247 /** @defgroup FileAccess File Access
+00248 *   @ingroup SpacecraftFramework
+00249 *  Spacecraft file access  
+00250 *  @{
+00251 */
+00252         
+00253 public:
+00259         Rotation GetOrbitalInertialRotation();
+00260 
+00266         void SetName(string _Name);
+00267         void OutputSTKAttitude();
+00268         void LoadFromFile(); 
+00269         void SaveToFile(); 
+00270 
+00271 private:
+00272         string m_Name;
+00273 };
+00274 
+00275 #endif 
+00276  // end of FileAccess // end of SpacecraftFramework
+00278 // END Spacecraft.h: interface for the Spacecraft class.
+

Generated on Thu Feb 27 13:46:17 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Spacecraft_8h.html b/doc/html/Spacecraft_8h.html new file mode 100644 index 0000000..f512269 --- /dev/null +++ b/doc/html/Spacecraft_8h.html @@ -0,0 +1,113 @@ + + +Spacecraft.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft.h File Reference

interface for the Spacecraft class. Provides a simple interface to model a spacecraft's attitude & orbital dynamics. +More... +

+#include "../Toolboxes/RungeKutta.h"
+#include "../Toolboxes/AstroToolbox.h"
+#include "../Toolboxes/Rotation/Rotation.h"
+#include "../Toolboxes/Cmatrix"
+#include <string>
+#include <fstream>
+#include "..\TOOLBOXES\ROTATION\Rotation.h"
+ +

+Go to the source code of this file. + + + + + + + + +

Compounds

class  Spacecraft

Defines

#define MAX_TORQUE   0.9
#define MIN_TORQUE   -0.9

Typedefs

typedef matrix< double > Matrix
+


Detailed Description

+interface for the Spacecraft class. Provides a simple interface to model a spacecraft's attitude & orbital dynamics. +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2001-2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+ Fix to work w/ new rotation toolbox
+

+


Define Documentation

+

+ + + + +
+ + +
#define MAX_TORQUE   0.9 +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
#define MIN_TORQUE   -0.9 +
+
+ + + + + +
+   + + +

+

+


Typedef Documentation

+

+ + + + +
+ + +
typedef matrix<double> Matrix +
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Spacecraft__Sim_8cpp.html b/doc/html/Spacecraft__Sim_8cpp.html new file mode 100644 index 0000000..713f816 --- /dev/null +++ b/doc/html/Spacecraft__Sim_8cpp.html @@ -0,0 +1,155 @@ + + +Spacecraft_Sim.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft_Sim.cpp File Reference

#include "Spacecraft.h"
+#include "../Toolboxes/AstroToolbox.h"
+#include "../Toolboxes/RungeKutta.h"
+#include <fstream>
+ + + + + + + +

Functions

Matrix yFunc (double time, Matrix StateVariables, Matrix Constants)
void RungeTest ()
void SpacecraftTest ()
int main ()
+

Function Documentation

+

+ + + + +
+ + + + + + + + + +
int main  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
void RungeTest  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
void SpacecraftTest  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrix yFunc double   time,
Matrix   StateVariables,
Matrix   Constants
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:19 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/TestRotation_8cpp.html b/doc/html/TestRotation_8cpp.html new file mode 100644 index 0000000..6ab19d1 --- /dev/null +++ b/doc/html/TestRotation_8cpp.html @@ -0,0 +1,76 @@ + + +TestRotation.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members  
+

TestRotation.cpp File Reference

#include "Rotation.h"
+#include "cmatrix"
+#include <fstream>
+ + + + + + +

Typedefs

typedef matrix< double > Matrix

Functions

int main ()
+

Typedef Documentation

+

+ + + + +
+ + +
typedef matrix<double> Matrix +
+
+ + + + + +
+   + + +

+

+


Function Documentation

+

+ + + + +
+ + + + + + + + + +
int main  
+
+ + + + + +
+   + + +

+

+


Generated on Wed Jan 22 13:11:49 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/Trigonometry_8h-source.html b/doc/html/Trigonometry_8h-source.html new file mode 100644 index 0000000..90fffaa --- /dev/null +++ b/doc/html/Trigonometry_8h-source.html @@ -0,0 +1,63 @@ + + +Trigonometry.h Source File + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Trigonometry.h

Go to the documentation of this file.
00001 
+00002 
+00008 
+00010 
+00011 
+00013 
+00018 #ifndef TRIGONOMETRY_H
+00019 #define TRIGONOMETRY_H
+00020 typedef double Angle;
+00021 const double PI = 3.14159; 
+00031 Angle DMS2Deg(double _Degrees, double _Minutes, double _Seconds)
+00032 {
+00033     return _Degrees + _Minutes / 60 + _Seconds / 3600;
+00034 }
+00035 
+00044 void Deg2DMS(Angle _Angle, double &Degrees, double &Minutes, double &Seconds)
+00045 {
+00046     Degrees = floor(_Angle);
+00047     Minutes = floor((_Angle - Degrees) * 60);
+00048     Seconds = (_Angle - Degrees - Minutes / 60) * 3600;
+00049 }
+00050 
+00058 Angle DMS2Rad(double _Degrees,double _Minutes, double _Seconds)
+00059 {
+00060     return DMS2Deg(_Degrees, _Minutes, _Seconds) * PI / 180;
+00061 }
+00062 
+00068 Angle Deg2Rad(Angle _Degrees)
+00069 {
+00070     return _Degrees * PI / 180;
+00071 }
+00072 
+00080 void Rad2DMS(Angle _Radians, double &Degrees, double &Minutes, double &Seconds)
+00081 {
+00082     _Radians = _Radians * 180 / PI;
+00083     Deg2DMS(_Radians, Degrees, Minutes, Seconds);
+00084     return;
+00085 }
+00086 
+00092 Angle Rad2Deg(Angle _Radians)
+00093 {
+00094     return _Radians * 180 / PI;
+00095 }
+00101 inline double atanh(double z)
+00102 {
+00103     return 0.5 * log((1+z)/(1-z));
+00104 } // end of Trigonometry
+00106 #endif
+00107 /* end of TRIGONOMETRY_H */
+

Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/Trigonometry_8h.html b/doc/html/Trigonometry_8h.html new file mode 100644 index 0000000..8b87c65 --- /dev/null +++ b/doc/html/Trigonometry_8h.html @@ -0,0 +1,43 @@ + + +Trigonometry.h File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Trigonometry.h File Reference

Collection of additional trigonometry routines. +More... +

+ +

+Go to the source code of this file. + + + + + + + + + + + + + +

Typedefs

typedef double Angle

Functions

Angle DMS2Deg (double _Degrees, double _Minutes, double _Seconds)
void Deg2DMS (Angle _Angle, double &Degrees, double &Minutes, double &Seconds)
Angle DMS2Rad (double _Degrees, double _Minutes, double _Seconds)
Angle Deg2Rad (Angle _Degrees)
void Rad2DMS (Angle _Radians, double &Degrees, double &Minutes, double &Seconds)
Angle Rad2Deg (Angle _Radians)
double atanh (double z)

Variables

const double PI = 3.14159
+


Detailed Description

+Collection of additional trigonometry routines. +

+

Author:
+Andrew Turner <ajturner@vt.edu>
Version:
+0.1
Date:
+2003 ////////////////////////////////////////////////////////////////////////////////////////////////
Todo:
+ Add an 'Angle Class'?
+

+


Generated on Thu Feb 27 13:46:20 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/annotated.html b/doc/html/annotated.html new file mode 100644 index 0000000..73243ab --- /dev/null +++ b/doc/html/annotated.html @@ -0,0 +1,26 @@ + + +Annotated Index + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework Compound List

Here are the classes, structs, unions and interfaces with brief descriptions: + + + + + + + + + + +
AttitudeClass encapsulating the rotational attitude of a rigid body frame with respect to another frame. The Attitude class allows for the attitude to be stored, retrieved, history logged,
DirectionCosineMatrix
Environment
ModifiedRodriguezParameters
Orbit
Quaternion
RigidBodyEncapsulation of a rigid body simulation. The RigidBody class outlines an interface to the simulation of a rigid body, including rotation kinematics and dynamics
Rotation
Spacecraft
Zeit
+
Generated on Thu Feb 27 13:46:20 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/bug.html b/doc/html/bug.html new file mode 100644 index 0000000..c48b064 --- /dev/null +++ b/doc/html/bug.html @@ -0,0 +1,25 @@ + + +Bug List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Bug List +

+
+
File Rotation.cpp
Matrix class doesn't currently work +
+ +

+ +

+
File SpacecraftToolboxConstants.h
Matrix class doesn't currently work +
+
Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classAttitude-members.html b/doc/html/classAttitude-members.html new file mode 100644 index 0000000..1305983 --- /dev/null +++ b/doc/html/classAttitude-members.html @@ -0,0 +1,23 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Attitude Member List

This is the complete list of members for Attitude, including all inherited members. + + + + + + + + +
GetAngularAcceleration()Attitude
GetAngularVelocity()Attitude
GetAttitude(AttitudeFrame _Frame=m_Frame)Attitude
GetFrame()Attitude
SetAngularAcceleration(const Vector &_AngularAcceleration)Attitude
SetAngularVelocity(const Vector &_AngularVelocity)Attitude
SetAttitude(const Rotation &_Attitude, AttitudeFrame _Frame=NO_FRAME)Attitude
SetFrame(AttitudeFrame _Frame)Attitude

Generated on Thu Feb 27 13:46:20 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classAttitude.html b/doc/html/classAttitude.html new file mode 100644 index 0000000..e629b05 --- /dev/null +++ b/doc/html/classAttitude.html @@ -0,0 +1,333 @@ + + +Attitude class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Attitude Class Reference

Class encapsulating the rotational attitude of a rigid body frame with respect to another frame. The Attitude class allows for the attitude to be stored, retrieved, history logged,. +More... +

+#include <Attitude.h> +

+List of all members. + + + + + + + + + + + + + + + + + + +

Public Methods

Rotation GetAttitude (AttitudeFrame _Frame=m_Frame)
 Returns the current attitude. The rotation corresponding to the current attitude with respect to a specified reference frame. By default the rotation frame is the current stored (propagated in) reference frame.

AttitudeFrame GetFrame ()
 Returns the current attitude reference frame.

void SetFrame (AttitudeFrame _Frame)
 Set the rigid body attitude frame. Sets the current attitude reference frame of the rigid body. Changes the stored frame and equations of motion. Does not change change current attitude in reference frame to new attitude in specified frame.

void SetAttitude (const Rotation &_Attitude, AttitudeFrame _Frame=NO_FRAME)
 Set the rigid body attitude. Sets the current attitude of the rigid body given a rotation and reference frame.

Vector GetAngularVelocity ()
 Returns the current angular velocity.

Vector GetAngularAcceleration ()
 Returns the current angular acceleration.

void SetAngularVelocity (const Vector &_AngularVelocity)
 Sets the rigid body angular velocity. Sets the current angular velocity of the rigid body given an angular velocity matrix.

void SetAngularAcceleration (const Vector &_AngularAcceleration)
 Sets the rigid body angular acceleration. Sets the current angular acceleration of the rigid body given an angular acceleration matrix.

+


Detailed Description

+Class encapsulating the rotational attitude of a rigid body frame with respect to another frame. The Attitude class allows for the attitude to be stored, retrieved, history logged,. +

+

Todo:
+ Verify attitude is inheritable.
+

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + +
Vector Attitude::GetAngularAcceleration  
+
+ + + + + +
+   + + +

+Returns the current angular acceleration. +

+

Returns :
+vector of 3 components of the angular acceleration about the primary axes of the body (rad/s^2).
+

+ + + + +
+ + + + + + + + + +
Vector Attitude::GetAngularVelocity  
+
+ + + + + +
+   + + +

+Returns the current angular velocity. +

+

Returns :
+vector of 3 components of the angular velocities about the primary axes of the body (rad/s).
+

+ + + + +
+ + + + + + + + + + +
Rotation Attitude::GetAttitude AttitudeFrame   _Frame = m_Frame
+
+ + + + + +
+   + + +

+Returns the current attitude. The rotation corresponding to the current attitude with respect to a specified reference frame. By default the rotation frame is the current stored (propagated in) reference frame. +

+

Parameters:
+ + +
_Frame  +frame to return the current attitude in
+
Returns :
+rotation matrix describing the attitude from the given frame to the reference frame
+

+ + + + +
+ + + + + + + + + +
AttitudeFrame Attitude::GetFrame  
+
+ + + + + +
+   + + +

+Returns the current attitude reference frame. +

+

Returns :
+current attitude reference frame.
+

+ + + + +
+ + + + + + + + + + +
void Attitude::SetAngularAcceleration const Vector  _AngularAcceleration
+
+ + + + + +
+   + + +

+Sets the rigid body angular acceleration. Sets the current angular acceleration of the rigid body given an angular acceleration matrix. +

+

Parameters:
+ + +
_AngularAcceleration  +(double) - (3x1) vector of angular accelerations (rad/s^2)
+
+

+ + + + +
+ + + + + + + + + + +
void Attitude::SetAngularVelocity const Vector  _AngularVelocity
+
+ + + + + +
+   + + +

+Sets the rigid body angular velocity. Sets the current angular velocity of the rigid body given an angular velocity matrix. +

+

Parameters:
+ + +
_AngularVelocity  +(double) - (3x1) vector of angular velocities (rad/s)
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Attitude::SetAttitude const Rotation  _Attitude,
AttitudeFrame   _Frame = NO_FRAME
+
+ + + + + +
+   + + +

+Set the rigid body attitude. Sets the current attitude of the rigid body given a rotation and reference frame. +

+

Parameters:
+ + + +
_Attitude  +(Rotation) - attitude rotation ()
_Frame  +(AttitudeFrame) - integer describing specified reference frame of attitude
+
+

+ + + + +
+ + + + + + + + + + +
void Attitude::SetFrame AttitudeFrame   _Frame
+
+ + + + + +
+   + + +

+Set the rigid body attitude frame. Sets the current attitude reference frame of the rigid body. Changes the stored frame and equations of motion. Does not change change current attitude in reference frame to new attitude in specified frame. +

+

Parameters:
+ + +
_Frame  +(AttitudeFrame) - integer describing specified reference frame of attitude
+
+


The documentation for this class was generated from the following file: +
Generated on Thu Feb 27 13:46:20 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classCEnvironment-members.html b/doc/html/classCEnvironment-members.html new file mode 100644 index 0000000..ee3217f --- /dev/null +++ b/doc/html/classCEnvironment-members.html @@ -0,0 +1,29 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

CEnvironment Member List

This is the complete list of members for CEnvironment, including all inherited members. + + + + + + + + + + + + + + +
CEnvironment()CEnvironment
CEnvironment(const Spacecraft *_Satellite)CEnvironment
EarthVector()CEnvironment
GetBField()CEnvironment
GetForces()CEnvironment
GetOption(int _Option)CEnvironment
GetOptions()CEnvironment
GetTorques()CEnvironment
MoonVector()CEnvironment
SetOption(int _Option, bool _OptionFlag)CEnvironment
SetOptionsMatrix(Matrix _Options)CEnvironment
SetSpacecraft(Spacecraft *_Satellite)CEnvironment
SunVector()CEnvironment
~CEnvironment()CEnvironment [virtual]

Generated on Tue Jan 28 14:15:05 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/classCEnvironment.html b/doc/html/classCEnvironment.html new file mode 100644 index 0000000..6210688 --- /dev/null +++ b/doc/html/classCEnvironment.html @@ -0,0 +1,444 @@ + + +CEnvironment class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

CEnvironment Class Reference

#include <Environment.h> +

+List of all members. + + + + + + + + + + + + + + + + +

Public Methods

 CEnvironment ()
 CEnvironment (const Spacecraft *_Satellite)
virtual ~CEnvironment ()
void SetSpacecraft (Spacecraft *_Satellite)
Matrix GetTorques ()
Matrix GetForces ()
void SetOptionsMatrix (Matrix _Options)
Matrix GetOptions ()
void SetOption (int _Option, bool _OptionFlag)
bool GetOption (int _Option)
Matrix GetBField ()
Matrix EarthVector ()
Matrix SunVector ()
Matrix MoonVector ()
+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
CEnvironment::CEnvironment  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
CEnvironment::CEnvironment const Spacecraft  _Satellite
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
CEnvironment::~CEnvironment   [virtual]
+
+ + + + + +
+   + + +

+

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix CEnvironment::EarthVector  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix CEnvironment::GetBField  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix CEnvironment::GetForces  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
bool CEnvironment::GetOption int   _Option
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix CEnvironment::GetOptions  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix CEnvironment::GetTorques  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix CEnvironment::MoonVector  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void CEnvironment::SetOption int   _Option,
bool   _OptionFlag
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void CEnvironment::SetOptionsMatrix Matrix   _Options
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void CEnvironment::SetSpacecraft Spacecraft  _Satellite
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix CEnvironment::SunVector  
+
+ + + + + +
+   + + +

+

+


The documentation for this class was generated from the following files: +
Generated on Tue Jan 28 14:15:05 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/classDirectionCosineMatrix-members.html b/doc/html/classDirectionCosineMatrix-members.html new file mode 100644 index 0000000..62a2308 --- /dev/null +++ b/doc/html/classDirectionCosineMatrix-members.html @@ -0,0 +1,38 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

DirectionCosineMatrix Member List

This is the complete list of members for DirectionCosineMatrix, including all inherited members. + + + + + + + + + + + + + + + + + + + + + + + +
DirectionCosineMatrix()DirectionCosineMatrix
DirectionCosineMatrix(const DirectionCosineMatrix &_DCM)DirectionCosineMatrix
DirectionCosineMatrix(const Matrix &_DCM)DirectionCosineMatrix
DirectionCosineMatrix(const Vector &_EulerAngles, const int &_Sequence)DirectionCosineMatrix
DirectionCosineMatrix(const Vector &_EulerAxis, const double &_EulerAngle)DirectionCosineMatrix
DirectionCosineMatrix(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)DirectionCosineMatrix
DirectionCosineMatrix(const ModifiedRodriguezParameters &_MRP)DirectionCosineMatrix
DirectionCosineMatrix(const Quaternion &_quat)DirectionCosineMatrix
GetEulerAngles(const int &_Sequence) constDirectionCosineMatrix
GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle)DirectionCosineMatrix
GetMRPDirectionCosineMatrix
GetQuaternionDirectionCosineMatrix
operator *(const DirectionCosineMatrix &_DCM2) constDirectionCosineMatrix [inline]
operator+(const DirectionCosineMatrix &_DCM2) constDirectionCosineMatrix
operator-(const DirectionCosineMatrix &_DCM2) constDirectionCosineMatrix
operator~DirectionCosineMatrix
Set(const DirectionCosineMatrix &_DCM)DirectionCosineMatrix
Set(const Vector &_EulerAngles, const int &_Sequence)DirectionCosineMatrix
Set(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)DirectionCosineMatrix
Set(const Vector &_EulerAxis, const double &_EulerAngle)DirectionCosineMatrix
Set(const ModifiedRodriguezParameters &_MRP)DirectionCosineMatrix
Set(const Quaternion &_qIn)DirectionCosineMatrix
~DirectionCosineMatrix()DirectionCosineMatrix [inline, virtual]

Generated on Thu Feb 27 13:46:21 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classDirectionCosineMatrix.html b/doc/html/classDirectionCosineMatrix.html new file mode 100644 index 0000000..754cfa6 --- /dev/null +++ b/doc/html/classDirectionCosineMatrix.html @@ -0,0 +1,907 @@ + + +DirectionCosineMatrix class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

DirectionCosineMatrix Class Reference
+ +[Direction Cosine Matrix] +

#include <Rotation.h> +

+List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Methods

 DirectionCosineMatrix ()
virtual ~DirectionCosineMatrix ()
 DirectionCosineMatrix (const DirectionCosineMatrix &_DCM)
 DirectionCosineMatrix (const Matrix &_DCM)
 DirectionCosineMatrix (const Vector &_EulerAngles, const int &_Sequence)
 DirectionCosineMatrix (const Vector &_EulerAxis, const double &_EulerAngle)
 DirectionCosineMatrix (const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)
 DirectionCosineMatrix (const ModifiedRodriguezParameters &_MRP)
 DirectionCosineMatrix (const Quaternion &_quat)
void Set (const DirectionCosineMatrix &_DCM)
void Set (const Vector &_EulerAngles, const int &_Sequence)
void Set (const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)
void Set (const Vector &_EulerAxis, const double &_EulerAngle)
void Set (const ModifiedRodriguezParameters &_MRP)
void Set (const Quaternion &_qIn)
Vector GetEulerAngles (const int &_Sequence) const
void GetEulerAxisAngle (Vector &_EulerAxis, double &_EulerAngle)
DirectionCosineMatrix operator+ (const DirectionCosineMatrix &_DCM2) const
DirectionCosineMatrix operator- (const DirectionCosineMatrix &_DCM2) const
DirectionCosineMatrix operator * (const DirectionCosineMatrix &_DCM2) const

Public Attributes

ModifiedRodriguezParameters GetMRP () const
Quaternion GetQuaternion () const
DirectionCosineMatrix operator~ ()
+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix  
+
+ + + + + +
+   + + +

+Create a DCM equal to the identity matrix [1,0,0;0,1,0;0,0,1].

Returns :
+3x3 Direction Cosine Matrix equal to the identity matrix.
+

+ + + + +
+ + + + + + + + + +
virtual DirectionCosineMatrix::~DirectionCosineMatrix   [inline, virtual]
+
+ + + + + +
+   + + +

+Default deconstructor.

+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix const DirectionCosineMatrix &   _DCM
+
+ + + + + +
+   + + +

+Create a copy of a DCM from an existing DCM.

Parameters:
+ + +
_DCM  +3x3 Direction Cosine Matrix to be copied.
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix const Matrix  _DCM
+
+ + + + + +
+   + + +

+Create a copy of a DCM from an existing matrix of DCM values.

Parameters:
+ + +
_DCM  +3x3 matrix of DCM values to be copied.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix const Vector  _EulerAngles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Create a Direction Cosine Matrix (DCM) from Euler Angles.

Parameters:
+ + + +
_EulerAngles  +3x1 matrix of Euler Angles. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix const Vector  _EulerAxis,
const double &   _EulerAngle
+
+ + + + + +
+   + + +

+Create a Direction Cosine Matrix (DCM) from an Euler Axis and rotation.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector ( +).
_EulerAngle  +Angle rotation about axis ( +)[rad].
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix const double &   _Angle1,
const double &   _Angle2,
const double &   _Angle3,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Create a Direction Cosine Matrix (DCM) from Euler Angles.

Parameters:
+ + + + + +
_Angle1  +first angles in Euler angle set. [rad]
_Angle2  +second angles in Euler angle set. [rad]
_Angle3  +third angles in Euler angle set. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix const ModifiedRodriguezParameters  _MRP
+
+ + + + + +
+   + + +

+Create a Direction Cosine Matrix (DCM) from a vector of Modified Rodriguez Parameters (MRP).

Parameters:
+ + +
_MRP  +3x1 MRP to be converted.
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix::DirectionCosineMatrix const Quaternion  _quat
+
+ + + + + +
+   + + +

+Create a Direction Cosine Matrix (DCM) from a quaternion.

Parameters:
+ + +
_quat  +4x1 quaternion to be converted.
+
Returns :
+3x3 Direction Cosine Matrix.
+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + + +
Vector DirectionCosineMatrix::GetEulerAngles const int &   _Sequence const
+
+ + + + + +
+   + + +

+Convert a DCM to a set of Euler Angles.

Parameters:
+ + +
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
Returns :
+(3 x 1) Euler Angles based on given rotation sequence.
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void DirectionCosineMatrix::GetEulerAxisAngle Vector  _EulerAxis,
double &   _EulerAngle
+
+ + + + + +
+   + + +

+Convert the DCM to an Euler Axis and Angle.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector ( +).
_EulerAngle  +Angle rotation about axis ( +)[rad].
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix DirectionCosineMatrix::operator * const DirectionCosineMatrix &   _DCM2 const [inline]
+
+ + + + + +
+   + + +

+Determine the successive rotation of the DCMS through multiplication.

Parameters:
+ + +
_DCM2  +DCM to be multiplied by.
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix DirectionCosineMatrix::operator+ const DirectionCosineMatrix &   _DCM2 const
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two DCMs.

Parameters:
+ + +
_DCM2  +DCM to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix DirectionCosineMatrix::operator- const DirectionCosineMatrix &   _DCM2 const
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two DCMs.

Parameters:
+ + +
_DCM2  +DCM to be differenced with.
+
+

+ + + + +
+ + + + + + + + + + +
void DirectionCosineMatrix::Set const Quaternion  _qIn
+
+ + + + + +
+   + + +

+Set a DCM to the transformation of a quaternion. Equation:

Parameters:
+ + +
_qIn  +4x1 quaternion to be converted.
+
+

+ + + + +
+ + + + + + + + + + +
void DirectionCosineMatrix::Set const ModifiedRodriguezParameters  _MRP
+
+ + + + + +
+   + + +

+Set the DCM to the transformation of Modified Rodriguez Paramaters (MRP).

Parameters:
+ + +
_MRP  +3x1 matrix of Modified Rodriguez Parameters (MRP).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void DirectionCosineMatrix::Set const Vector  _EulerAxis,
const double &   _EulerAngle
+
+ + + + + +
+   + + +

+Set the DCM to the transformation of an Euler Axis and Angle.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector ( +).
_EulerAngle  +Angle rotation about axis ( +)[rad].
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void DirectionCosineMatrix::Set const double &   _Angle1,
const double &   _Angle2,
const double &   _Angle3,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Set the DCM to the transformation of set of Euler Angles.

Parameters:
+ + + + + +
_Angle1  +first angles in Euler angle set. [rad]
_Angle2  +second angles in Euler angle set. [rad]
_Angle3  +third angles in Euler angle set. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void DirectionCosineMatrix::Set const Vector  _EulerAngles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Set the DCM to the transformation of set of Euler Angles.

Parameters:
+ + + +
_EulerAngles  +3x1 matrix of Euler Angles. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + +
void DirectionCosineMatrix::Set const DirectionCosineMatrix &   _DCM
+
+ + + + + +
+   + + +

+Set a DCM to a copy of another DCM.

Parameters:
+ + +
_DCM  +3x3 DCM to be copied.
+
+


Member Data Documentation

+

+ + + + +
+ + +
ModifiedRodriguezParameters DirectionCosineMatrix::GetMRP +
+
+ + + + + +
+   + + +

+Convert a DCM to an MRP representation.

Returns :
+(3 x 1) converted MRP.
+

+ + + + +
+ + +
Quaternion DirectionCosineMatrix::GetQuaternion +
+
+ + + + + +
+   + + +

+Convert a DCM to a quaternion representation.

Returns :
+(4 x 1) converted quaternion.
+

+ + + + +
+ + +
DirectionCosineMatrix DirectionCosineMatrix::operator~() +
+
+ + + + + +
+   + + +

+Determines the inverse of a DCM by taking the transpose (same operation).

Returns :
+Inverse (transpose) of DCM.
+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:21 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classEnvironment-members.html b/doc/html/classEnvironment-members.html new file mode 100644 index 0000000..2a81143 --- /dev/null +++ b/doc/html/classEnvironment-members.html @@ -0,0 +1,29 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Environment Member List

This is the complete list of members for Environment, including all inherited members. + + + + + + + + + + + + + + +
EarthVector()Environment
Environment()Environment
Environment(const Spacecraft *_Satellite)Environment
GetBField()Environment
GetForces()Environment
GetOption(int _Option)Environment
GetOptions()Environment
GetTorques()Environment
MoonVector()Environment
SetOption(int _Option, bool _OptionFlag)Environment
SetOptionsMatrix(Matrix _Options)Environment
SetSpacecraft(Spacecraft *_Satellite)Environment
SunVector()Environment
~Environment()Environment [virtual]

Generated on Thu Feb 27 13:46:21 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classEnvironment.html b/doc/html/classEnvironment.html new file mode 100644 index 0000000..dcce312 --- /dev/null +++ b/doc/html/classEnvironment.html @@ -0,0 +1,447 @@ + + +Environment class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Environment Class Reference

#include <Environment.h> +

+List of all members. + + + + + + + + + + + + + + + + +

Public Methods

 Environment ()
 Environment (const Spacecraft *_Satellite)
virtual ~Environment ()
void SetSpacecraft (Spacecraft *_Satellite)
Matrix GetTorques ()
Matrix GetForces ()
void SetOptionsMatrix (Matrix _Options)
Matrix GetOptions ()
void SetOption (int _Option, bool _OptionFlag)
bool GetOption (int _Option)
Matrix GetBField ()
Matrix EarthVector ()
Matrix SunVector ()
Matrix MoonVector ()
+


Detailed Description

+Description: The Environment class will do all the computation for determining the external environment of a spacecraft. This includes, but is not limited to, gravity, torques, Sun Vector, Earth Vector, Magnetic Field, etc. This class is meant to be easily extensible. To use the environment, a pointer to the modelled spacecraft is given to the environment, which can then query the spacecraft as needed for relevant information (ie, position, ballistic coeff, magnetic dipole, etc.). To setup the environment, the user sets the appropriate options by passing either a matrix of the options, or individually setting options using the OPTION_ flags and a TRUE to activate the option, or a FALSE to deactivate the option. Whenever the forces or torques are queried, the appropriate options are included in the calculations. All Vectors returned are with respect to the Body-Frame as specified by the spacecraft's attitude. +

+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
Environment::Environment  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
Environment::Environment const Spacecraft  _Satellite
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Environment::~Environment   [virtual]
+
+ + + + + +
+   + + +

+

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix Environment::EarthVector  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Environment::GetBField  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Environment::GetForces  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
bool Environment::GetOption int   _Option
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Environment::GetOptions  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Environment::GetTorques  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Environment::MoonVector  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Environment::SetOption int   _Option,
bool   _OptionFlag
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void Environment::SetOptionsMatrix Matrix   _Options
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void Environment::SetSpacecraft Spacecraft  _Satellite
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Environment::SunVector  
+
+ + + + + +
+   + + +

+

+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:21 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classMatrix-members.html b/doc/html/classMatrix-members.html new file mode 100644 index 0000000..0b624d8 --- /dev/null +++ b/doc/html/classMatrix-members.html @@ -0,0 +1,16 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Matrix Member List

This is the complete list of members for Matrix, including all inherited members. + +
diag()Matrix

Generated on Tue Jan 28 14:31:50 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/classMatrix.html b/doc/html/classMatrix.html new file mode 100644 index 0000000..c2e6c6c --- /dev/null +++ b/doc/html/classMatrix.html @@ -0,0 +1,52 @@ + + +Matrix class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Matrix Class Reference

#include <Matrix.h> +

+List of all members. + + + +

Public Methods

 diag ()
+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix::diag  
+
+ + + + + +
+   + + +

+

+


The documentation for this class was generated from the following file: +
Generated on Tue Jan 28 14:31:50 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/classModifiedRodriguezParameters-members.html b/doc/html/classModifiedRodriguezParameters-members.html new file mode 100644 index 0000000..b4bdb64 --- /dev/null +++ b/doc/html/classModifiedRodriguezParameters-members.html @@ -0,0 +1,40 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

ModifiedRodriguezParameters Member List

This is the complete list of members for ModifiedRodriguezParameters, including all inherited members. + + + + + + + + + + + + + + + + + + + + + + + + + +
AutoSwitch(bool _SwitchBoolean=true)ModifiedRodriguezParameters
GetDCMModifiedRodriguezParameters
GetEulerAngles(int _Sequence) constModifiedRodriguezParameters
GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle) constModifiedRodriguezParameters
GetQuaternionModifiedRodriguezParameters
ModifiedRodriguezParameters()ModifiedRodriguezParameters
ModifiedRodriguezParameters(const ModifiedRodriguezParameters &_MRP)ModifiedRodriguezParameters
ModifiedRodriguezParameters(double _s1, double _s2, double _s3)ModifiedRodriguezParameters
ModifiedRodriguezParameters(const Vector &_sVector)ModifiedRodriguezParameters
ModifiedRodriguezParameters(const DirectionCosineMatrix &_DCM)ModifiedRodriguezParameters
ModifiedRodriguezParameters(const Vector &_Angles, const int &_Sequence)ModifiedRodriguezParameters
ModifiedRodriguezParameters(const Vector &_EulerAxis, const double &_EulerAngle)ModifiedRodriguezParameters
ModifiedRodriguezParameters(const Quaternion &_qIN)ModifiedRodriguezParameters
operator+(const ModifiedRodriguezParameters &_MRP2) constModifiedRodriguezParameters
operator-(const ModifiedRodriguezParameters &_MRP2) constModifiedRodriguezParameters
Set(const ModifiedRodriguezParameters &_MRP)ModifiedRodriguezParameters
Set(double _s1, double _s2, double _s3)ModifiedRodriguezParameters
Set(const Vector &_sVector)ModifiedRodriguezParameters
Set(const DirectionCosineMatrix &_DCM)ModifiedRodriguezParameters
Set(const Vector &_EulerAngles, const int &_Sequence)ModifiedRodriguezParameters
Set(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)ModifiedRodriguezParameters
Set(const Vector &_EulerAxis, const double &_EulerAngle)ModifiedRodriguezParameters
Set(const Quaternion &_qIN)ModifiedRodriguezParameters
ShadowSetModifiedRodriguezParameters
Switch(int _SwitchThreshold=1)ModifiedRodriguezParameters

Generated on Thu Feb 27 13:46:22 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classModifiedRodriguezParameters.html b/doc/html/classModifiedRodriguezParameters.html new file mode 100644 index 0000000..819f910 --- /dev/null +++ b/doc/html/classModifiedRodriguezParameters.html @@ -0,0 +1,927 @@ + + +ModifiedRodriguezParameters class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

ModifiedRodriguezParameters Class Reference
+ +[Modified Rodriguez Parameters] +

#include <Rotation.h> +

+List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Methods

 ModifiedRodriguezParameters ()
 ModifiedRodriguezParameters (const ModifiedRodriguezParameters &_MRP)
 ModifiedRodriguezParameters (double _s1, double _s2, double _s3)
 ModifiedRodriguezParameters (const Vector &_sVector)
 ModifiedRodriguezParameters (const DirectionCosineMatrix &_DCM)
 ModifiedRodriguezParameters (const Vector &_Angles, const int &_Sequence)
 ModifiedRodriguezParameters (const Vector &_EulerAxis, const double &_EulerAngle)
 ModifiedRodriguezParameters (const Quaternion &_qIN)
void Set (const ModifiedRodriguezParameters &_MRP)
void Set (double _s1, double _s2, double _s3)
void Set (const Vector &_sVector)
void Set (const DirectionCosineMatrix &_DCM)
void Set (const Vector &_EulerAngles, const int &_Sequence)
void Set (const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)
void Set (const Vector &_EulerAxis, const double &_EulerAngle)
void Set (const Quaternion &_qIN)
Vector GetEulerAngles (int _Sequence) const
void GetEulerAxisAngle (Vector &_EulerAxis, double &_EulerAngle) const
void Switch (int _SwitchThreshold=1)
void AutoSwitch (bool _SwitchBoolean=true)
ModifiedRodriguezParameters operator+ (const ModifiedRodriguezParameters &_MRP2) const
ModifiedRodriguezParameters operator- (const ModifiedRodriguezParameters &_MRP2) const

Public Attributes

DirectionCosineMatrix GetDCM () const
Quaternion GetQuaternion () const
ModifiedRodriguezParameters ShadowSet ()
+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters  
+
+ + + + + +
+   + + +

+Default Constructor. Create an MRP set with intial value of [0,0,0]^T.

+

+ + + + +
+ + + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters const ModifiedRodriguezParameters &   _MRP
+
+ + + + + +
+   + + +

+Copy Constructor. Create a copy of an MRP set.

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters double   _s1,
double   _s2,
double   _s3
+
+ + + + + +
+   + + +

+Create an MRP set based on 3 values.

Parameters:
+ + + + +
_s1  +first MRP value.
_s2  +second MRP value.
_s3  +third MRP value.
+
+

+ + + + +
+ + + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters const Vector  _sVector
+
+ + + + + +
+   + + +

+Create an MRP set from a vector 3 values.

Parameters:
+ + +
_sVector  +3x1 vector of MRP values.
+
+

+ + + + +
+ + + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters const DirectionCosineMatrix  _DCM
+
+ + + + + +
+   + + +

+Create an MRP set converted from a Direction Cosine Matrix (DCM).

Parameters:
+ + +
_DCM  +3x3 Direction Cosine Matrix (DCM) to be converted.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters const Vector  _Angles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Create an MRP set from an Euler Angle sequence.

Parameters:
+ + + +
_Angles  +3x1 matrix of euler angles. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters const Vector  _EulerAxis,
const double &   _EulerAngle
+
+ + + + + +
+   + + +

+Create the MRP from an Euler Axis and Angle.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector ( +).
_EulerAngle  +Angle rotation about axis ( +)[rad].
+
+

+ + + + +
+ + + + + + + + + + +
ModifiedRodriguezParameters::ModifiedRodriguezParameters const Quaternion  _qIN
+
+ + + + + +
+   + + +

+Create an MRP set converted from a quaternion.

Parameters:
+ + +
_DCM  +4x1 quaternion to be converted.
+
+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + + +
void ModifiedRodriguezParameters::AutoSwitch bool   _SwitchBoolean = true
+
+ + + + + +
+   + + +

+Sets the MRP set to automatically switch between the normal set and the shadow set based on the shortest rotational distance to the origin.

Parameters:
+ + +
_SwitchBoolean  +boolean value where TRUE turns on switching, and FALSE turns off switching.
+
+

+ + + + +
+ + + + + + + + + + +
Vector ModifiedRodriguezParameters::GetEulerAngles int   _Sequence const
+
+ + + + + +
+   + + +

+Convert the MRP vector to a set of Euler Angles.

Parameters:
+ + +
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
Returns :
+3x1 vector of euler angles.
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void ModifiedRodriguezParameters::GetEulerAxisAngle Vector  _EulerAxis,
double &   _EulerAngle
const
+
+ + + + + +
+   + + +

+Convert the MRP vector to the Euler Axis and Angle set.

Parameters:
+ + +
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
Returns :
+3x1 vector of euler angles.
+

+ + + + +
+ + + + + + + + + + +
ModifiedRodriguezParameters ModifiedRodriguezParameters::operator+ const ModifiedRodriguezParameters &   _MRP2 const
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two MRP vectors.

Parameters:
+ + +
_MRP2  +MRP vector to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
ModifiedRodriguezParameters ModifiedRodriguezParameters::operator- const ModifiedRodriguezParameters &   _MRP2 const
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two MRP vectors.

Parameters:
+ + +
_MRP2  +MRP vector to be differenced with.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void ModifiedRodriguezParameters::Set const Vector  _EulerAxis,
const double &   _EulerAngle
+
+ + + + + +
+   + + +

+Set the MRP from the transformation of an Euler Axis and Angle.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector ( +).
_EulerAngle  +Angle rotation about axis ( +)[rad].
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void ModifiedRodriguezParameters::Set const double &   _Angle1,
const double &   _Angle2,
const double &   _Angle3,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Set the MRP from the transformation of set of Euler Angles.

Parameters:
+ + + + + +
_Angle1  +first angles in Euler angle set. [rad]
_Angle2  +second angles in Euler angle set. [rad]
_Angle3  +third angles in Euler angle set. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void ModifiedRodriguezParameters::Set const Vector  _EulerAngles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Set the MRP from the transformation of set of Euler Angles.

Parameters:
+ + + +
_EulerAngles  +3x1 matrix of Euler Angles. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + +
void ModifiedRodriguezParameters::Set const DirectionCosineMatrix  _DCM
+
+ + + + + +
+   + + +

+Set the MRP from a converted Direction Cosine Matrix (DCM).

Parameters:
+ + +
_DCM  +3x3 Direction Cosine Matrix (DCM) to be converted
+
+

+ + + + +
+ + + + + + + + + + +
void ModifiedRodriguezParameters::Set const Vector  _sVector
+
+ + + + + +
+   + + +

+Set the MRP set from a vector 3 values.

Parameters:
+ + +
_sVector  +3x1 vector of MRP values.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void ModifiedRodriguezParameters::Set double   _s1,
double   _s2,
double   _s3
+
+ + + + + +
+   + + +

+Set the MRP vector based on 3 values.

Parameters:
+ + + + +
_s1  +first MRP value.
_s2  +second MRP value.
_s3  +third MRP value.
+
+

+ + + + +
+ + + + + + + + + + +
void ModifiedRodriguezParameters::Set const ModifiedRodriguezParameters &   _MRP
+
+ + + + + +
+   + + +

+Set the MRP to the copy of an existing MRP vector

Parameters:
+ + +
_MRP  +MRP Vector to be copied
+
+

+ + + + +
+ + + + + + + + + + +
void ModifiedRodriguezParameters::Switch int   _SwitchThreshold = 1
+
+ + + + + +
+   + + +

+Switches the MRP vector to the shortest rotational distance back to the origin using the shadow set if the magnitude of the vector is greater than the input value S.

Parameters:
+ + +
_SwitchThreshold  +magnitude of the MRP vector at which the set is switched. A positive scalar number.
+
+


Member Data Documentation

+

+ + + + +
+ + +
DirectionCosineMatrix ModifiedRodriguezParameters::GetDCM +
+
+ + + + + +
+   + + +

+Convert the MRP vector to a Direction Cosine Matrix (DCM).

Returns :
+3x3 Direction Cosine Matrix.
+

+ + + + +
+ + +
Quaternion ModifiedRodriguezParameters::GetQuaternion +
+
+ + + + + +
+   + + +

+Convert the MRP vector to a quaternion.

Returns :
+4x1 quaternion.
+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:22 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classOrbit-members.html b/doc/html/classOrbit-members.html new file mode 100644 index 0000000..30103e0 --- /dev/null +++ b/doc/html/classOrbit-members.html @@ -0,0 +1,28 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Orbit Member List

This is the complete list of members for Orbit, including all inherited members. + + + + + + + + + + + + + +
GetInclination()Orbit
GetOrbitalAngularVelocity()Orbit
GetOrbitalElements()Orbit
GetPosition()Orbit
GetPositionVelocity()Orbit
GetPositionVelocity(Matrix &_Position, Matrix &_Velocity)Orbit
GetVelocity()Orbit
Orbit()Orbit
SetControlForces(Matrix _ControlForces)Orbit
SetOrbitalElements(Matrix _orbitalElements)Orbit
SetPositionVelocity(Matrix _Position, Matrix _Velocity)Orbit
SetPositionVelocity(Matrix _InertialPosition, Matrix _InertialVelocity)Orbit
~Orbit()Orbit [virtual]

Generated on Thu Feb 27 13:46:22 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classOrbit.html b/doc/html/classOrbit.html new file mode 100644 index 0000000..2274cba --- /dev/null +++ b/doc/html/classOrbit.html @@ -0,0 +1,257 @@ + + +Orbit class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Orbit Class Reference
+ +[Orbital Toolbox] +

#include <Orbit.h> +

+List of all members. + + + + + + + + + + + + + + + +

Public Methods

 Orbit ()
virtual ~Orbit ()
void SetOrbitalElements (Matrix _orbitalElements)
void SetPositionVelocity (Matrix _Position, Matrix _Velocity)
Matrix GetOrbitalElements ()
Matrix GetPositionVelocity ()
void GetPositionVelocity (Matrix &_Position, Matrix &_Velocity)
Matrix GetPosition ()
Matrix GetVelocity ()
double GetOrbitalAngularVelocity ()
double GetInclination ()
void SetPositionVelocity (Matrix _InertialPosition, Matrix _InertialVelocity)
void SetControlForces (Matrix _ControlForces)
+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
Orbit::Orbit  
+
+ + + + + +
+   + + +

+Default Constructor.

+

+ + + + +
+ + + + + + + + + +
Orbit::~Orbit   [virtual]
+
+ + + + + +
+   + + +

+Default Deconstructor.

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix Orbit::GetOrbitalElements  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Orbit::GetPositionVelocity Matrix  _Position,
Matrix  _Velocity
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Orbit::GetPositionVelocity  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void Orbit::SetOrbitalElements Matrix   _orbitalElements
+
+ + + + + +
+   + + +

+Set the orbit based on classical orbital elements (Keplerian).

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Orbit::SetPositionVelocity Matrix   _Position,
Matrix   _Velocity
+
+ + + + + +
+   + + +

+

+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:22 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classQuaternion-members.html b/doc/html/classQuaternion-members.html new file mode 100644 index 0000000..fc9524c --- /dev/null +++ b/doc/html/classQuaternion-members.html @@ -0,0 +1,36 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Quaternion Member List

This is the complete list of members for Quaternion, including all inherited members. + + + + + + + + + + + + + + + + + + + + + +
GetDCMQuaternion
GetEulerAngles(const int &_Sequence) constQuaternion
GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle)Quaternion
GetMRPQuaternion
Normalize()Quaternion
operator+(const Quaternion &_quat2) constQuaternion
operator-(const Quaternion &_quat2) constQuaternion
Quaternion()Quaternion
Quaternion(double _q1, double _q2, double _q3, double _q4)Quaternion
Quaternion(const Vector &_qVector)Quaternion
Quaternion(const DirectionCosineMatrix &_DCM)Quaternion
Quaternion(const Vector &_EulerAngles, const int &_Sequence)Quaternion
Quaternion(const Vector &_EulerAxis, const double &_EulerAngle)Quaternion
Quaternion(const ModifiedRodriguezParameters &_MRP)Quaternion
Set(const Quaternion &_qIn)Quaternion
Set(double _q1, double _q2, double _q3, double _q4)Quaternion
Set(const Vector &_qVector)Quaternion
Set(const DirectionCosineMatrix &_DCM)Quaternion
Set(const Vector &_EulerAngles, const int &_Sequence)Quaternion
Set(const Vector &_EulerAxis, const double &_EulerAngle)Quaternion
Set(const ModifiedRodriguezParameters &_MRP)Quaternion

Generated on Thu Feb 27 13:46:22 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classQuaternion.html b/doc/html/classQuaternion.html new file mode 100644 index 0000000..199ae02 --- /dev/null +++ b/doc/html/classQuaternion.html @@ -0,0 +1,849 @@ + + +Quaternion class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Quaternion Class Reference
+ +[Quaternion Attitude Representation] +

#include <Rotation.h> +

+List of all members. + + + + + + + + + + + + + + + + + + + + + + + + +

Public Methods

 Quaternion ()
 Quaternion (double _q1, double _q2, double _q3, double _q4)
 Quaternion (const Vector &_qVector)
 Quaternion (const DirectionCosineMatrix &_DCM)
 Quaternion (const Vector &_EulerAngles, const int &_Sequence)
 Quaternion (const Vector &_EulerAxis, const double &_EulerAngle)
 Quaternion (const ModifiedRodriguezParameters &_MRP)
void Normalize ()
void Set (const Quaternion &_qIn)
void Set (double _q1, double _q2, double _q3, double _q4)
void Set (const Vector &_qVector)
void Set (const DirectionCosineMatrix &_DCM)
void Set (const Vector &_EulerAngles, const int &_Sequence)
void Set (const Vector &_EulerAxis, const double &_EulerAngle)
void Set (const ModifiedRodriguezParameters &_MRP)
Vector GetEulerAngles (const int &_Sequence) const
void GetEulerAxisAngle (Vector &_EulerAxis, double &_EulerAngle)
Quaternion operator+ (const Quaternion &_quat2) const
Quaternion operator- (const Quaternion &_quat2) const

Public Attributes

DirectionCosineMatrix GetDCM () const
ModifiedRodriguezParameters GetMRP () const
+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
Quaternion::Quaternion  
+
+ + + + + +
+   + + +

+Create a quaternion with initial value of [0,0,0,1]^T.

Returns :
+(double) - (4 x 1) quaternion = [0,0,0,1]^T.
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Quaternion::Quaternion double   _q1,
double   _q2,
double   _q3,
double   _q4
+
+ + + + + +
+   + + +

+Create a quaternion with initial values.

Parameters:
+ + + + + +
_q1  +first quaternin parameter
_q2  +second quaternin parameter
_q3  +third quaternin parameter
_q4  +fourth quaternin parameter
+
Returns :
+(double) - (4 x 1) quaternion = [_q1,_q2,_q3,_q4]^T.
+

+ + + + +
+ + + + + + + + + + +
Quaternion::Quaternion const Vector  _qVector
+
+ + + + + +
+   + + +

+Create a quaternion with initial value of the input 4x1 matrix.

Parameters:
+ + +
_qMatrix  +4x1 matrix of quaternion elements.
+
Returns :
+(double) - (4 x 1) quaternion.
+

+ + + + +
+ + + + + + + + + + +
Quaternion::Quaternion const DirectionCosineMatrix  _DCM
+
+ + + + + +
+   + + +

+Create a quaternion from a direction cosine matrix (DCM).

Parameters:
+ + +
_DCM  +3x3 Direction Cosine Matrix to be transformed.
+
Returns :
+(double) - (4 x 1) quaternion.
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Quaternion::Quaternion const Vector  _EulerAngles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Create a quaternion from a set of Euler Angles and Sequence.

Parameters:
+ + + +
_EulerAngles  +3x1 matrix of Euler Angles. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Quaternion::Quaternion const Vector  _EulerAxis,
const double &   _EulerAngle
+
+ + + + + +
+   + + +

+Create a quaternion from the transformation about an Euler Axis by a set angle.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector.
_EulerAngle  +Angle rotation about axis [rad].
+
+

+ + + + +
+ + + + + + + + + + +
Quaternion::Quaternion const ModifiedRodriguezParameters  _MRP
+
+ + + + + +
+   + + +

+Create a Quaternion from the transformation of Modified Rodriguez Paramaters (MRP).

Parameters:
+ + +
_MRP  +3x1 matrix of Modified Rodriguez Parameters (MRP).
+
+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + + +
Vector Quaternion::GetEulerAngles const int &   _Sequence const
+
+ + + + + +
+   + + +

+Convert the quaternion to a set of Euler Angles.

Parameters:
+ + +
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
Returns :
+(3 x 1) Euler Angles based on given rotation sequence ( +)[rad]
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Quaternion::GetEulerAxisAngle Vector  _EulerAxis,
double &   _EulerAngle
+
+ + + + + +
+   + + +

+Convert the quaternion to an Euler Axis and Angle.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector ( +).
_EulerAngle  +Angle rotation about axis ( +)[rad].
+
+

+ + + + +
+ + + + + + + + + +
void Quaternion::Normalize  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
Quaternion Quaternion::operator+ const Quaternion &   _quat2 const
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two quaternions.

Parameters:
+ + +
_quat2  +Quaternion to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
Quaternion Quaternion::operator- const Quaternion &   _quat2 const
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two quaternions.

Parameters:
+ + +
_quat2  +Quaternion to be differenced with.
+
+

+ + + + +
+ + + + + + + + + + +
void Quaternion::Set const ModifiedRodriguezParameters  _MRP
+
+ + + + + +
+   + + +

+Set the Quaternion to the transformation of Modified Rodriguez Paramaters (MRP).

Parameters:
+ + +
_MRP  +3x1 matrix of Modified Rodriguez Parameters (MRP).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Quaternion::Set const Vector  _EulerAxis,
const double &   _EulerAngle
+
+ + + + + +
+   + + +

+Set the quaternion to the transformation about an Euler Axis by a set angle.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis vector ( +).
_EulerAngle  +Angle rotation about axis ( +)[rad].
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Quaternion::Set const Vector  _EulerAngles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Set the quaternion to the transformation of set of Euler Angles.

Parameters:
+ + + +
_EulerAngles  +3x1 matrix of Euler Angles. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + +
void Quaternion::Set const DirectionCosineMatrix  _DCM
+
+ + + + + +
+   + + +

+Sets the current quaternion from a converted Direction Cosine Matrix (DCM).

Parameters:
+ + +
_DCM  +3x3 DCM to be converted.
+
+

+ + + + +
+ + + + + + + + + + +
void Quaternion::Set const Vector  _qVector
+
+ + + + + +
+   + + +

+Sets the quaternion with the values of the input 4x1 matrix.

Parameters:
+ + +
_qMatrix  +4x1 matrix of quaternion elements.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Quaternion::Set double   _q1,
double   _q2,
double   _q3,
double   _q4
+
+ + + + + +
+   + + +

+Sets the quaternion to the values specified.

Parameters:
+ + + + + +
_q1  +first quaternin parameter
_q2  +second quaternin parameter
_q3  +third quaternin parameter
_q4  +fourth quaternin parameter
+
+

+ + + + +
+ + + + + + + + + + +
void Quaternion::Set const Quaternion &   _qIn
+
+ + + + + +
+   + + +

+Set the quaternion to a copy of another quaternion.

Parameters:
+ + +
_qIn  +Quaternion to be copied.
+
+


Member Data Documentation

+

+ + + + +
+ + +
DirectionCosineMatrix Quaternion::GetDCM +
+
+ + + + + +
+   + + +

+Convert the quaternion to a Direction Cosine Matrix (DCM). Uses the DirectionCosineMatrix(Quaternion) constructor.

Returns :
+3x3 Direction Cosine Matrix.
+

+ + + + +
+ + +
ModifiedRodriguezParameters Quaternion::GetMRP +
+
+ + + + + +
+   + + +

+Convert the quaternion to an MRP representation. Uses the ModifiedRodriguezParameters(Quaternion) constructor.

Returns :
+(3 x 1) converted MRP.
+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:22 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classRigidBody-members.html b/doc/html/classRigidBody-members.html new file mode 100644 index 0000000..2d1ecbb --- /dev/null +++ b/doc/html/classRigidBody-members.html @@ -0,0 +1,21 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

RigidBody Member List

This is the complete list of members for RigidBody, including all inherited members. + + + + + + +
GetAppliedTorques()RigidBody
GetAttitude()RigidBody
GetMomentsInertia()RigidBody
Propagate(double StartTime, double EndTime, int numSteps=100)RigidBody
RigidBody()RigidBody
SetMomentsInertia(const Matrix &_momentsInertia)RigidBody

Generated on Thu Feb 27 13:46:23 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classRigidBody.html b/doc/html/classRigidBody.html new file mode 100644 index 0000000..0e10e97 --- /dev/null +++ b/doc/html/classRigidBody.html @@ -0,0 +1,254 @@ + + +RigidBody class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

RigidBody Class Reference

Encapsulation of a rigid body simulation. The RigidBody class outlines an interface to the simulation of a rigid body, including rotation kinematics and dynamics. +More... +

+#include <RigidBody.h> +

+List of all members. + + + + + + + + + + + + + +

Public Methods

 RigidBody ()
 Default Constructor.

Matrix GetMomentsInertia ()
 Returns the moments of inertia of the rigid body.

void SetMomentsInertia (const Matrix &_momentsInertia)
 Sets the moments of inertia of the rigid body.

Matrix GetAppliedTorques ()
 Returns the external rigid body torques.

AttitudeGetAttitude ()
 Returns a pointer to the current rigid body attitude representation. All setting and inspecting of the attitude should be done through this pointer.

void Propagate (double StartTime, double EndTime, int numSteps=100)
+


Detailed Description

+Encapsulation of a rigid body simulation. The RigidBody class outlines an interface to the simulation of a rigid body, including rotation kinematics and dynamics. +

+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
RigidBody::RigidBody  
+
+ + + + + +
+   + + +

+Default Constructor. +

+

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix RigidBody::GetAppliedTorques  
+
+ + + + + +
+   + + +

+Returns the external rigid body torques. +

+

Returns :
+Matrix<double> - (3x1) matrix of external torques along primary body axes (N-m).
+

+ + + + +
+ + + + + + + + + +
Attitude* RigidBody::GetAttitude  
+
+ + + + + +
+   + + +

+Returns a pointer to the current rigid body attitude representation. All setting and inspecting of the attitude should be done through this pointer. +

+

Returns :
+pointer the current attitude representation.
+

+ + + + +
+ + + + + + + + + +
Matrix RigidBody::GetMomentsInertia  
+
+ + + + + +
+   + + +

+Returns the moments of inertia of the rigid body. +

+

Returns :
+Matrix<double> - (3x3) matrix of moments of inertia (kg-m^2).
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void RigidBody::Propagate double   StartTime,
double   EndTime,
int   numSteps = 100
+
+ + + + + +
+   + + +

+Propagation through time. Propagates the satellites attitude dynamics through time based on reference frame.

Parameters:
+ + + + +
StartTime  +(double): initial time of integration, measured since epoch (s)
EndTime  +(double): final time of integration, measured since epoch (s)
numSteps  +(double): number of integration steps to use
+
Returns :
+(double) - (n x 8) matrix of time history of attitude states [time,q1,q2,q3,q4,w1,w2,w3] (units as before)
+

+ + + + +
+ + + + + + + + + + +
void RigidBody::SetMomentsInertia const Matrix  _momentsInertia
+
+ + + + + +
+   + + +

+Sets the moments of inertia of the rigid body. +

+

Parameters:
+ + +
_momentsInertia  +(Matrix<double>) - (3x3) matrix of spacecraft moments of inertia (kg-m^2).
+
+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:22 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classRotation-members.html b/doc/html/classRotation-members.html new file mode 100644 index 0000000..43c9a07 --- /dev/null +++ b/doc/html/classRotation-members.html @@ -0,0 +1,40 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation Member List

This is the complete list of members for Rotation, including all inherited members. + + + + + + + + + + + + + + + + + + + + + + + + + +
GetDCMRotation
GetEulerAngles(const int &_Sequence)Rotation
GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle) constRotation
GetMRPRotation
GetQuaternionRotation
Rotation()Rotation
Rotation(const Matrix &_inMatrix)Rotation
Rotation(const DirectionCosineMatrix &_DCM)Rotation
Rotation(const Vector &_Angles, const int &_Sequence)Rotation
Rotation(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)Rotation
Rotation(const Vector &_Axis, const double &_Angle)Rotation
Rotation(const ModifiedRodriguezParameters &_MRP)Rotation
Rotation(const Quaternion &_quat)Rotation
Rotation::operator *(const Rotation &_rot2) constRotation
Rotation::operator+(const Rotation &_rot2) constRotation
Rotation::operator-(const Rotation &_rot2) constRotation
Rotation::operator~() constRotation
Set(const Matrix &_inMatrix)Rotation
Set(const DirectionCosineMatrix &_DCM)Rotation
Set(const Vector &_Angles, const int &_Sequence)Rotation
Set(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)Rotation
Set(const Vector &_Axis, const double &_Angle)Rotation
Set(const ModifiedRodriguezParameters &_MRP)Rotation
Set(const Quaternion &_quat)Rotation
~Rotation()Rotation

Generated on Thu Feb 27 13:46:23 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classRotation.html b/doc/html/classRotation.html new file mode 100644 index 0000000..5308f3b --- /dev/null +++ b/doc/html/classRotation.html @@ -0,0 +1,960 @@ + + +Rotation class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation Class Reference
+ +[Rotation] +

#include <Rotation.h> +

+List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Methods

 Rotation ()
 Rotation (const Matrix &_inMatrix)
 Rotation (const DirectionCosineMatrix &_DCM)
 Rotation (const Vector &_Angles, const int &_Sequence)
 Rotation (const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)
 Rotation (const Vector &_Axis, const double &_Angle)
 Rotation (const ModifiedRodriguezParameters &_MRP)
 Rotation (const Quaternion &_quat)
 ~Rotation ()
void Set (const Matrix &_inMatrix)
void Set (const DirectionCosineMatrix &_DCM)
void Set (const Vector &_Angles, const int &_Sequence)
void Set (const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)
void Set (const Vector &_Axis, const double &_Angle)
void Set (const ModifiedRodriguezParameters &_MRP)
void Set (const Quaternion &_quat)
Vector GetEulerAngles (const int &_Sequence)
void GetEulerAxisAngle (Vector &_EulerAxis, double &_EulerAngle) const
Rotation Rotation::operator * (const Rotation &_rot2) const
Rotation Rotation::operator~ () const
Rotation Rotation::operator+ (const Rotation &_rot2) const
Rotation Rotation::operator- (const Rotation &_rot2) const

Public Attributes

DirectionCosineMatrix GetDCM () const
ModifiedRodriguezParameters GetMRP () const
Quaternion GetQuaternion () const
+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
Rotation::Rotation  
+
+ + + + + +
+   + + +

+Default Constructor. Create a Rotation with no offset.

+

+ + + + +
+ + + + + + + + + + +
Rotation::Rotation const Matrix  _inMatrix
+
+ + + + + +
+   + + +

+Create a Rotation from a direction cosine matrix.

Parameters:
+ + +
_inMatrix  +3x3 matrix of Direction Cosine Matrix (DCM) values.
+
+

+ + + + +
+ + + + + + + + + + +
Rotation::Rotation const DirectionCosineMatrix  _DCM
+
+ + + + + +
+   + + +

+Create a Rotation from a direction cosine matrix.

Parameters:
+ + +
_DCM  +instance of Direction Cosine Matrix (DCM) class.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Rotation::Rotation const Vector  _Angles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Create a Rotation from an euler angle sequence.

Parameters:
+ + + +
_Angles  +3x1 matrix of euler angles.
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rotation::Rotation const double &   _Angle1,
const double &   _Angle2,
const double &   _Angle3,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Create a Rotation from an euler angle sequence.

Parameters:
+ + + + + +
_Angle1  +first angles in Euler angle set. [rad]
_Angle2  +second angles in Euler angle set. [rad]
_Angle3  +third angles in Euler angle set. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Rotation::Rotation const Vector  _Axis,
const double &   _Angle
+
+ + + + + +
+   + + +

+Create a Rotation from a given euler axis and angle.

Parameters:
+ + + +
Axis  +3x1 Euler Axis
Angle  +Angle rotation about axis [rad].
+
+

+ + + + +
+ + + + + + + + + + +
Rotation::Rotation const ModifiedRodriguezParameters  _MRP
+
+ + + + + +
+   + + +

+Create a Rotation from a given set of Modified Rodriguez Parameters.

Parameters:
+ + +
_MRP  +3x1 MRP vector to be represented.
+
+

+ + + + +
+ + + + + + + + + + +
Rotation::Rotation const Quaternion  _quat
+
+ + + + + +
+   + + +

+Create a Rotation from a given quaternion.

Parameters:
+ + +
_quat  +4x1 quaternion to be represented.
+
+

+ + + + +
+ + + + + + + + + +
Rotation::~Rotation  
+
+ + + + + +
+   + + +

+Default Destructor.

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + + +
Vector Rotation::GetEulerAngles const int &   _Sequence
+
+ + + + + +
+   + + +

+Return the Euler angles from the rotation representation.

Parameters:
+ + +
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
Returns :
+_Angles 3x1 matrix of euler angles.
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Rotation::GetEulerAxisAngle Vector  _EulerAxis,
double &   _EulerAngle
const
+
+ + + + + +
+   + + +

+Return the Euler Axis and Angle form of the attitude transformation.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis to be returned.
_EulerAngle  +Euler angle of rotation [rad].
+
+

+ + + + +
+ + + + + + + + + + +
Rotation Rotation::Rotation::operator * const Rotation &   _rot2 const
+
+ + + + + +
+   + + +

+Multiply the rotation matrices together.

Returns :
+3x3 Direction Cosine Matrix (DCM).
+

+ + + + +
+ + + + + + + + + + +
Rotation Rotation::Rotation::operator+ const Rotation &   _rot2 const
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two rotations.

Parameters:
+ + +
_rot2  +Rotation to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
Rotation Rotation::Rotation::operator- const Rotation &   _rot2 const
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two rotations.

Parameters:
+ + +
_rot2  +Rotation to be differenced with.
+
+

+ + + + +
+ + + + + + + + + +
Rotation Rotation::Rotation::operator~   const
+
+ + + + + +
+   + + +

+Take the inverse of the rotation matrix.

Returns :
+3x3 Direction Cosine Matrix (DCM).
+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set const Quaternion  _quat
+
+ + + + + +
+   + + +

+Set the Rotation from a converted quaternion.

Parameters:
+ + +
_quat  +4x1 quaternion to set the Rotation.
+
+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set const ModifiedRodriguezParameters  _MRP
+
+ + + + + +
+   + + +

+Set the Rotation from a converted vector of MRP.

Parameters:
+ + +
_MRP  +3x1 vector of Modified Rodriguez Parameters to set the Rotation.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Rotation::Set const Vector  _Axis,
const double &   _Angle
+
+ + + + + +
+   + + +

+Set the Rotation from a converted Euler Axis and Angle set.

Parameters:
+ + + +
_Axis  +3x1 Euler Axis.
_Angle  +Angle rotation about axis [rad].
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Rotation::Set const double &   _Angle1,
const double &   _Angle2,
const double &   _Angle3,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Create a Rotation from an euler angle sequence.

Parameters:
+ + + + + +
_Angle1  +first angles in Euler angle set. [rad]
_Angle2  +second angles in Euler angle set. [rad]
_Angle3  +third angles in Euler angle set. [rad]
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Rotation::Set const Vector  _Angles,
const int &   _Sequence
+
+ + + + + +
+   + + +

+Set the Rotation from an euler angle sequence.

Parameters:
+ + + +
_Angles  +3x1 matrix of euler angles.
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set const DirectionCosineMatrix  _DCM
+
+ + + + + +
+   + + +

+Set the Rotation from a converted DCM.

Parameters:
+ + +
_DCM  +3x3 matrix of Direction Cosine Matrix (DCM) values.
+
+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set const Matrix  _inMatrix
+
+ + + + + +
+   + + +

+Set the Rotation from a converted DCM.

Parameters:
+ + +
_inMatrix  +3x3 matrix of Direction Cosine Matrix (DCM) values.
+
+


Member Data Documentation

+

+ + + + +
+ + +
DirectionCosineMatrix Rotation::GetDCM +
+
+ + + + + +
+   + + +

+Return the Direction Cosine Matrix (DCM) form of the attitude transformation.

Returns :
+3x3 Direction Cosine Matrix (DCM).
+

+ + + + +
+ + +
ModifiedRodriguezParameters Rotation::GetMRP +
+
+ + + + + +
+   + + +

+Return the Modified Rodriguez Parameters vector form of the attitude transformation.

Returns :
+3x1 MRP vector.
+

+ + + + +
+ + +
Quaternion Rotation::GetQuaternion +
+
+ + + + + +
+   + + +

+Return the quaternion form of the attitude transformation.

Returns :
+4x1 quaternion.
+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:23 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classSpacecraft-members.html b/doc/html/classSpacecraft-members.html new file mode 100644 index 0000000..f69e2dc --- /dev/null +++ b/doc/html/classSpacecraft-members.html @@ -0,0 +1,35 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Member List

This is the complete list of members for Spacecraft, including all inherited members. + + + + + + + + + + + + + + + + + + + + +
EOM_bi(double time, Matrix stateVariables, Matrix constantsInput)Spacecraft [static]
EOM_bo(double time, Matrix stateVariables, Matrix constantsInput)Spacecraft [static]
EOM_bo_Linear(double time, Matrix stateVariables, Matrix constantsInput)Spacecraft [static]
GetControlHistory(double _beginTime=-1, double _endTime=-1)Spacecraft
GetFlightHistory(double _beginTime=-1, double _endTime=-1, AttitudeFrame _Frame=NO_FRAME)Spacecraft
GetFlightHistory(AttitudeFrame _Frame)Spacecraft
GetMomentsInertia()Spacecraft
GetOrbitalInertialRotationSpacecraft
GetSpacecraftTorques()Spacecraft
LoadFromFile()Spacecraft
OutputSTKAttitude()Spacecraft
Propagate(double StartTime, double EndTime, int numSteps=100)Spacecraft
ResetFlightHistory()Spacecraft
SaveToFile()Spacecraft
SetMomentsInertia(Matrix _momentsInertia)Spacecraft
SetName(string _Name)Spacecraft
SetNumHistorySteps(int _numSteps)Spacecraft
Spacecraft()Spacecraft
Spacecraft(Quaternion AttitudeQuaternion, Matrix AngularVelocity, Matrix AngularAcceleration, Matrix InertialPosition, Matrix InertialVelocity)Spacecraft
~Spacecraft()Spacecraft [virtual]

Generated on Thu Feb 27 13:46:23 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classSpacecraft.html b/doc/html/classSpacecraft.html new file mode 100644 index 0000000..17fe0fe --- /dev/null +++ b/doc/html/classSpacecraft.html @@ -0,0 +1,50 @@ + + +Spacecraft class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Class Reference
+ +[Spacecraft Framework] +

#include <Spacecraft.h> +

+List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Methods

 Spacecraft ()
 Spacecraft (Quaternion AttitudeQuaternion, Matrix AngularVelocity, Matrix AngularAcceleration, Matrix InertialPosition, Matrix InertialVelocity)
virtual ~Spacecraft ()
void Propagate (double StartTime, double EndTime, int numSteps=100)
Matrix GetMomentsInertia ()
Matrix GetSpacecraftTorques ()
void SetMomentsInertia (Matrix _momentsInertia)
void SetNumHistorySteps (int _numSteps)
void ResetFlightHistory ()
Matrix GetFlightHistory (double _beginTime=-1, double _endTime=-1, AttitudeFrame _Frame=NO_FRAME)
Matrix GetFlightHistory (AttitudeFrame _Frame)
Matrix GetControlHistory (double _beginTime=-1, double _endTime=-1)
void SetName (string _Name)
void OutputSTKAttitude ()
 Saves the spacecraft attitude history in an STK attitude file (saved as 'm_Name'.a).

void LoadFromFile ()
 Loads the spacecraft parameters from a file - need to set the spacecraft name first.

void SaveToFile ()
 Saves all the spacecraft parameters to file based on the spacecraft name (Not Complete).


Static Public Methods

Matrix EOM_bi (double time, Matrix stateVariables, Matrix constantsInput)
Matrix EOM_bo (double time, Matrix stateVariables, Matrix constantsInput)
Matrix EOM_bo_Linear (double time, Matrix stateVariables, Matrix constantsInput)

Public Attributes

Rotation GetOrbitalInertialRotation ()
+


The documentation for this class was generated from the following files: +
Generated on Thu Feb 27 13:46:23 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classZeit-members.html b/doc/html/classZeit-members.html new file mode 100644 index 0000000..814c08c --- /dev/null +++ b/doc/html/classZeit-members.html @@ -0,0 +1,21 @@ + + +Member List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Zeit Member List

This is the complete list of members for Zeit, including all inherited members. + + + + + + +
GetMJD()Zeit
GetUT()Zeit
Set()Zeit
SetMJD(Matrix _MJD)Zeit
SetUT(matrix UT)Zeit
Zeit()Zeit

Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/classZeit.html b/doc/html/classZeit.html new file mode 100644 index 0000000..6381c91 --- /dev/null +++ b/doc/html/classZeit.html @@ -0,0 +1,203 @@ + + +Zeit class Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Zeit Class Reference
+ +[Time representation] +

#include <SpacecraftTime.h> +

+List of all members. + + + + + + + + +

Public Methods

 Zeit ()
void Set ()
 SetUT (matrix UT)
Matrix GetUT ()
void SetMJD (Matrix _MJD)
Matrix GetMJD ()
+


Constructor & Destructor Documentation

+

+ + + + +
+ + + + + + + + + +
Zeit::Zeit  
+
+ + + + + +
+   + + +

+

+


Member Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix Zeit::GetMJD  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Zeit::GetUT  
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
void Zeit::Set  
+
+ + + + + +
+   + + +

+Sets the time to current system time.

+

+ + + + +
+ + + + + + + + + + +
void Zeit::SetMJD Matrix   _MJD
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
Zeit::SetUT matrix   UT
+
+ + + + + +
+   + + +

+

+


The documentation for this class was generated from the following file: +
Generated on Thu Feb 27 13:46:23 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/doxygen.css b/doc/html/doxygen.css new file mode 100644 index 0000000..e527a57 --- /dev/null +++ b/doc/html/doxygen.css @@ -0,0 +1,49 @@ +H1 { text-align: center; } +CAPTION { font-weight: bold } +A.qindex {} +A.qindexRef {} +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code { text-decoration: none; font-weight: normal; color: #4444ee } +A.codeRef { font-weight: normal; color: #4444ee } +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +DIV.fragment { width: 100%; border: none; background-color: #eeeeee } +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } +TD.md { background-color: #f2f2ff; font-weight: bold; } +TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; } +TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; } +DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } +DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } +BODY { background: white } +TD.indexkey { + background-color: #eeeeff; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +TD.indexvalue { + background-color: #eeeeff; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +span.keyword { color: #008000 } +span.keywordtype { color: #604020 } +span.keywordflow { color: #e08000 } +span.comment { color: #800000 } +span.preprocessor { color: #806020 } +span.stringliteral { color: #002080 } +span.charliteral { color: #008080 } diff --git a/doc/html/doxygen.png b/doc/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..96ae72c2978be48bb081e0795f5e9a5d6905a5b9 GIT binary patch literal 2352 zcmaJ@XHXM}5)Mc=AW}p^5e%RSEsY{YdPy*fgck593B?GZMk&IDB6^_&r6UR=V1t07 zqDYYB{P-jdO973>Gf8e9NRM)Dp)o!g0qM<4Vj=zPe@|Dq666;okhst+uYS@xk zAe#!=^Zln?PyVKr%6E;`S(kqWY=*HsfA1V;)fhQ<$CMos^=cI}FxoX8aHZD(`7N&D z>eW}uY`q&yA(Aq{v|hyY~*BV!IpRizEa^A zSwUf5fG8o|FrCa?7W_ZsbCSbIMfvD5rc2)xa_CE)&3MK>PdiZzPSx=EY{5R=Lw9$W zFB~Q4-_erioglSItWbyFcScK%P|Bx2nok_;7V~gL{^sw)Hmw`$rsv1K}`8Yt2#c0pX2g5sO;y1o~4%iuIyi#qw zFm*RC`MvCuf!1<4v?T_#Q{Sw>Dv=96=Qk`bvEfC+V}+C_G!9f5qp+Mfqpdo&v-7X2 zEsjl=2Zs2jpeR3I^jOrC#EnCRYK7ykw~Y<^$KBzQ$j?=wli)Z_dg%f@3mh@mn~ zY-rW-_)2Tp)x!)>H?E^r>=E{}#T=G-CW-@osY zch;71#~zaaQaCN&u+y;iqyJD$efQ0`ds~0bG7EEg?iz@?@KkW>xdI>kcON*eM-mkj z{Hg4Mq|yM@aKlnN8Ad!tqDiW7k~_vI0!L4-1Z&Wup7|~d>#qjJ0-uA&ia#r&mdx8v zh{Ysj=iMgA&&1A@moF|nsz(e)_;Uiol|tq()vU(gqOB|ji;{rH_>zyt2xSg9h+h{C zv+F5Xy#5KK7P)%}Ck#D|^?1V$N)szVm7J2X#m+w(imL|lM%~vBw^Q~q$CrnXoTf$H zzF~>!<$mS2O?lzwP|kfiF}g8jcl3mUEgkkkh%w!KZMvAFF9^}~ej@k#Gd^V_{0z7E zlS6D1*YZT=yhuXqJ9{VQ#HEDN*DR$8sI6F7<;IiQSrcoeN7g_o#?!`Af^b9`2;50K zitSJI72p0Sb8pZ7DS_NNl_sYR+va{vYOi<{J}UY2dXxVnRvC@qh1F8VTgYH6vT~(% zZ2N{=>^>N0x=jb@(&D^o^RLm}($~_;&Kub{C2Xfmah^5anC-b6$;BEl3*$8jem8}c z3*MM|I(n@y9TAF*ctIWJT!UQdUmM^y{K3@8sQJdNrafkJtINN7ONa1e;w?Mt{_JhM zvRka(c#HYT@E0V`S6xwQ!o-vU4DQhKh-)xd(lG?l6971ya~`Kg%#4-Zl9lG!@VLCj zn%e5Mm!q<2O$UGcRpXu>y%9VED_L9OY%qWuy3i~< z+emnMRoLY#-xm~rEgRP6atqF;dvM1{=%Q7NcKcBg&Z1l zV~6}Z`XPV+=bsYaz2&oFCc3ZEn}yXbvh;enHYUk;@jUTd(xG51%O-4mi-__eW*D%0++`&?dm# zPd_nXLUL4%gBDan;34>)_!5SOs{V7u1HVyR7H*pVx$aUUgqXX95@2i(7j1|H^I|!M zS3hU81OfgU9~=o25UZE}Kn~T?I2_2;b7HMR`%*)h);W}}SN$d(wjY3w22CPf3pSEK z`@JL}GUw`L^lZx+{KurgBTG8o(X~G|(-<9c9%;J8&^(JEc$Oi*N?=TC)Lzw#&F7Nl zHQB3u-YV(8aQrkAK!U7fLifRwqTWQcQt+0@;kmR<&^uK8n9YK;XTuDH?XY{HL*v09 z8svU;%Hhy$AH9$^e+pAEde;2I<;K%f*-dV3{IarZHE-WX1+D)GFP8KnOsc_^ z6q~mV=laSj_m1;^5X}%ECLfW5I$=E3`=TMVtLt?(a30*5=_&F*bvhx?FF`d>rP;x^MFfsMbkCxS5D-e^%!V{JsKKS`i`&ka` z-g#uQghXfa@Au4JFJ6eWrAEFVsOiW@X;hgN@VQgD2(fD=RxXatsl;WS2C1NQ5IP1br%vg@40K^|6=DP_ zk`iN1j)|m@h&uj}I)0bKLPIDz#87e&KcIbI4*IVgDKNyBa(Q1*52cUvH89j85a4h> zq`m + +File Index + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework File List

Here is a list of all files with brief descriptions: + + + + + + + + + + + + + + + + + + + + + +
AstroToolbox.h [code]
Attitude.h [code]Interface to the Attitude class
Environment.cpp
Environment.h [code]Encapsulation of various environmental effects for modelling spacecraft motion and attitude dynamics
main.cpp
Matrix.cpp
Matrix.h [code]Wrapper of tvmet Matrix Library
Orbit.cpp
Orbit.h [code]Interface for the Orbit class
Plot.h [code]Interface to GNUPLOT (http://www.gnuplot.org)
RigidBody.cppImplementation of the Rigid Body class
RigidBody.h [code]Interface definition to the Rigid Body class
Rotation.cppImplementation of Rotation Namespace Objects. Provides a set of functions to use Rotation matrices and their various representations
Rotation.h [code]Rotation toolkit. Provides a set of functions to use Rotation matrices and their various representations
RungeKutta.h [code]Runge-Kutta integrator
Spacecraft.cpp
Spacecraft.h [code]Interface for the Spacecraft class. Provides a simple interface to model a spacecraft's attitude & orbital dynamics
Spacecraft_Sim.cpp
SpacecraftTime.h [code]
SpacecraftToolboxConstants.h [code]Collection of typical constants used for spacecraft analysis and operations
Trigonometry.h [code]Collection of additional trigonometry routines
+
Generated on Thu Feb 27 13:46:15 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/form_0.png b/doc/html/form_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b2d0aeec03f346e3aa7838787e647de50247db36 GIT binary patch literal 642 zcmV-|0)737P)*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*J07*naRCt_YU>I6}{eA;pdDi_4i7|%xejtAN`9;`-4N;vMRwt|?e zCNMC>&sdLa7lW+wf^e|{3sImu*k(-ziR@RSFrMuwQ^d4WVim)1wazmpd5@;0FI^;9p>gu;+irdf^ESoPQI5#s~n7$$R(i-D{3- z4E+L3{}HObF>rifxTXJFfI$x^{|;)*Tp-;61PMT{pdjZ31}3r3P-DP=9b^pGe1xiR z3_vH}RIoY#H+a5-{sMoX#|41^$gLOPV)@9x#n1{fhI8%&2FAZYPc7{S0B8&YB7Q{~e}Jfd0m1u7Y6M`2ft3MjjQ*in0m#O1E=A@s z@GSt5>mAruVb2s?mmsuTGFE9A*y;u(7}FAP$xoNUs~rmT{(r+O&;9=wF~+E+CE}GA cO9Ofa0Bk&!_IuRR?EnA(07*qoM6N<$f_I@B6#xJL literal 0 HcmV?d00001 diff --git a/doc/html/form_1.png b/doc/html/form_1.png new file mode 100644 index 0000000000000000000000000000000000000000..ee694cfca8958b85301fc4b3d1932fac3678032e GIT binary patch literal 559 zcmV+~0?_@5P)*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*Itw}^dRCt_YU>GRC-a?V~ZhHgl62=O|Xcywgu3f(CJ8n(A4`3|j zX#!YP=o{Q;5H`jx#~}Fu#`6EKfL#gGch*zCRUEL&aX_@|zJJUph{J(;q4Eq5*$Z%K z@95}I_{fXHbwJC1&a!4az_kFEc0oZw<^z0CKFi4@G<)R!|KJQ~-~emaS|N!l+51BQ zNHQL2g7V`F`WG+(X`quj5|GsKJODZ5H}ii8Hv=f$0Hg&WK4yd|`_I6?U_MwJETelD z3huqVd-pomCx-hB4AVjCfzm+lN^~HBHmG(Hgry*5P$29i!21!Xo#PimS}Y9?GN+{g z1>OU-uLqht69~Y8pa4^v+b_WR8K^z{7Lbz(l%9Yhy=xtav_Cw5fjv?z%m+rSDVSx# zAHewD{XbK~Ee34TN%COIjUPojC|#HVJz;FfFaww}lkW4b{2zc#nrRtCgnvQ40fv0c z`c3-pLBjVLnExnXla9X+5y`(AhN7LxrP4+51D}9e8j#C!uYffTtF&7R0~P==o_T`| xHc5ig40B!@fLu2fdy*$44F)E74**wrlO7`;)WrY*002ovPDHLkV1fh{?0NtI literal 0 HcmV?d00001 diff --git a/doc/html/form_10.png b/doc/html/form_10.png new file mode 100644 index 0000000000000000000000000000000000000000..411b1983c8c11f151c66df764aad9fc00b4c0302 GIT binary patch literal 1018 zcmV*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*Kcu7P-RCt{2mrrQZP#nj9uW8z(YnS%m5J6TDodp4He%>c=d>ZJL!J>-A?S2o31PSZQalC{r#jqaB2{@@TbE_|K zslM!De+n4uPh+z;3CiozBK!b`V1<()VVP7ab(^%7*7hyIex}B81G8nUqh?;g7C2B_ z>zRNhO2Yb}O8A0@9=|{!5bzT$5}oDF_7q&zQBR-W2V6k2LwMj8!Mbu|Di#e+!#9Co zsj(;+W&)fJ12Us!V=Lo7mS9msg{piexH~H=NSY;V`!?gphGT)8 zN4d%hl4b>qL`Tu6lIKuGt|Gz9niVY03G+IMZgMnGd<$M%$$Ayr9D!I6Vm#5TV09Tx ziU~I?p#@I@YA^ICl2>@R2cCLC(S8fN=)me6-g0ilCl%=wbiRf#7Y!24B6d-^z_}e~ z!=4qa&SLCc_^RBv2l&z9npH)!g2j88{v$cEJwmW)hkBz&#yZhEqFI_?pJ@FbkOIpS z>>01R?bPyHuE3ot=qH*bY~69a^q}39XP>u@0NbldXdpsgO0X>g(f+}l@Hem@XL5F- o-7{-rkH#Z*vAg1e-741O7kZ{RQ$p}rG5`Po07*qoM6N<$f>Axvwg3PC literal 0 HcmV?d00001 diff --git a/doc/html/form_11.png b/doc/html/form_11.png new file mode 100644 index 0000000000000000000000000000000000000000..a98b99bc03f2aa6b28b713dd2df0031d877575b5 GIT binary patch literal 1035 zcmV+m1oZofP)*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*KiAh93RCt{2*6(Z7b{q%rck)f{a`9r)!C;Db*@La351J~St`EE$ z{=$M#hNu;tL8OXM?8fTj16R4Z2R$}nh>G#YraSiFVE;f-5TES^qaso*C`>^xwN^YI zh~HekmnLcOzPB9+!w<(@65ihz$v5A8F2FmeBPF}tAsb4?mYL~F>rAW$Dzhy!Q<1$s zv*iHtCD0}-muqZm>rgx>KKFlzw6@t?a{#HPN8`z2<6CfbgO3$@Az0oA6@d-NIK+*_ zi0OUz0;-eaWWQf#jW4%`ml>FAVwyvuLocl&^UA}O26QXWHwofwW~>JHZvy$%`I%&v z)Ci`CtJyg4+dV#3ajAm&V|BWfEiPiu&;p*`VC)2L@v&(aS<0F_MwP10j;gV_6~qa~ z{s5PE5^!ina2--kIoH@xX);p`r-+?p>`}GIxxo52=eXb03r;|xy zy9XjmYC{dN8vAJxn=_@xmR!I-;->5bc7{xbk8;R|FeZDTLq%H|E)=3;Dpn~M+Wo$7~Lzfi_swEfd| z_w#>b>0ikmq4<@@YL0GsY*1JJ4eMX7?Bb>9(7!gy+B@K}N~u&j89H0J)!gO`Z7_DW z>Lgwe?4wN|OY8^quG0(X>gqB=tl&zKCAElMYQuk^-QU@(HMJ9K5*Hi`@Uo`AGuv!_ay8{7rCETBl{N`$#ojFjl$y@i z=sQ^7Ao>dE`yvQ%v6s_E1$B86`sF;Egvg6%y1G{#?3YJB2?AW~tq*Vtx9REi9G^e} zt6S^y&~{%Jg8&!1@wIWvdmls|XBXIoNyr=Ytya7E=UforVhfpalYPdHDo&_R_Lw*Z z?K|ub0$glWD*9|rDYK(uO|^r_l44r7maek0L4b?>cAHfBtg`(o(!tY!UAse>lLcYy z$JEYmg24Z?Cv=>>Kkc-Oj!d^^w+*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*KWl2OqRCt{2mD@`cQ5?s==Na47U*(_}a`+$+j(iwZof+Xn_ZlsT;1<+p5Jg7yMz~*TuN&rGsf;0+W z+F0skMaEzSeX9=cutzc;wQ=C6?CWX+mT4ufy@!ua7n>y?=LDulqQQM1H@>aMFEFwv z;Dh7$SY#7ePE^gz((0_*D>BBMtCETpePERAz^1XE>1lBMh%uIt`6iB?;SyTN# zoH;dY5AOk&s~BS}%41lkJeAO@a4-FtFnOA~+vDo$hO5s@U@r|;z3O=UsFQjUNN7y0 zoIaLH9N@`8%Hjr1+r;8cr|n`buX_ zR`rBs<$?q@k4GW2!_dgQoyJvf44bJi5rhq@fo;j(^NjvkCV>-tafuliVvA?p#iT|i zSoFMty^TNx*yy-~7l3Z^Fv76vMW&f#gSUj-sAL zFQFNEOO4Irn}{L}OHb9ndM4a2Klr@tL*-W-XiZ4;grBLCv(HF`X3kqGBdqQlPJR1x ziB?#wo2+CEn=~>Lx_hCmGVPm?u5F2${o1K%+p+80F4l~t1xrVvxwO6W4pv$jn37qt zbdB4@vSL<^h2aX?O|{P^mJ^wAYB(8483g!*xc>kD|G|R?7cN{laNxj( z4I36LSTJG2gocKOf`WpCgoJ>A00##L0|NsE1qA^C0iY%+Mw9tKim@cfFPOpM*^M+H z$K2D!F{ENnazX=>n1SVL1`h*mm4+KimFFS97jJimd#<6ox%!=(8Kx$F%sm^`)1 d*#+2F2r#g&=ct&__zGkmgQu&X%Q~loCIHEjI<^1+ literal 0 HcmV?d00001 diff --git a/doc/html/form_14.png b/doc/html/form_14.png new file mode 100644 index 0000000000000000000000000000000000000000..130436e3827c8041f10b481cc322166ae3823442 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=%3?!FCJ6-`&1_3@HuK)l4fAHYJg$oxB95}FH z!-fS57EG8hp`oFnpr9ZjAt4|jz`?=6z`#I3K|w%30H{fd(PTc5Vk`;r3ubV5b|VeQ zarAU?45^rtoY26SoXjd9`uQw_OJzOt#|mXT9rmDX3%e7{uK9&E5Bw7nPCWmSz%P=r o_NN)=l1ZPLBYw|`XEd11P*o?OQN$i34m6Cx)78&qol`;+0No2f#{d8T literal 0 HcmV?d00001 diff --git a/doc/html/form_15.png b/doc/html/form_15.png new file mode 100644 index 0000000000000000000000000000000000000000..240fbebc4f6f16ad9871f3be1c2a10f406931d07 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^d?3ui3?$#C89V|~1_3@HuK)l4fAHYJg$oxB95}FH z!-fS57EG8hp`oFnpr9ZjAt4|jz`?=6z`#I3K|w%30H{fd(PTc5Vk`;r3ubV5b|VeQ z@%40Z45^rtoY26m#>!z^YB(b){sQZ=pQ34vFRR+36Mp?Ylh30t^}d9?kqE;}|2NVz z93RR56g?!}@MY3U9wRn~S+0$a=NOX~g)!X`Vn`9>zrh*9kqk7L!PC{xWt~$(69CQ6 BM*IK( literal 0 HcmV?d00001 diff --git a/doc/html/form_16.png b/doc/html/form_16.png new file mode 100644 index 0000000000000000000000000000000000000000..7ff64606c9f0b8c98781ea2ea7b83b4eb6394141 GIT binary patch literal 386 zcmV-|0e$|7P)*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*I07*naRCt_YV4yWHAgrW;pbF-NgjBGUM+q=63t);Pm~!l#2@Lt4 zF_ds3nARM;42&DJFqC95FbIR30mN+GMGOoYg&sNaPAWK(aJCK|S1O*HXT?{-Ex)^#HJ_3at7#R2ua2)`$jxfwZSk%S9kg*F$0+rl* z_ilszi{1}F(GLvIfn)~|Bmk8#^9FQ5lz@Q!MnMqufEi@5AP|5|VX9{>OV07*qoM6N<$f~-N3KL7v# literal 0 HcmV?d00001 diff --git a/doc/html/form_17.png b/doc/html/form_17.png new file mode 100644 index 0000000000000000000000000000000000000000..8059cf601499fc0cea7bbe225e38241d0ca5f884 GIT binary patch literal 345 zcmV-f0jB*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*H*GWV{RCt_YV4xT@AhB5^92m@;7}P=;v{ynzm;#Wbvlu_KPRM86 zz!k87%>gXJE`TI$&hV9AK$v3z%Yy~1U~R0mrBEp_m+eBlX#?*9=8x91z=A6{xS^(t zgNSH@euFHKGy~XB_6w>U3mDisfS_jqkk9z3pTQn14FxP< zd+7ztA0X1)2@SSTyF-BZC&LSQ279&*>9J?jy00000NkvXXu0mjf{|tj+ literal 0 HcmV?d00001 diff --git a/doc/html/form_18.png b/doc/html/form_18.png new file mode 100644 index 0000000000000000000000000000000000000000..ad051e13cbcefddaa1bbc1f58f2c19694502c774 GIT binary patch literal 336 zcmV-W0k8gvP)*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*H&PhZ;RCt_YU?3SV8VcZ%U0?GNw|KSw?VJ&0mVqiyT%e{*LK*b*zZZIeUg^hv0 z0O(gi1OSRYVEn}51Ej;!($XA&v^WqWyt71Ffw2O~MSeg$0nTFq+W$xaA4O*SeJB+Hhs7BLZvEC>J{%Fn>r ih(i_#TorK3K>+|x+cmY!OT;?>0000*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*K3Q0skRCt`tmQ85WU>L`rB<;Gc?bJG)5}2D zllXCoV{{&5ouCInnBP<{?PahY#&U4Nc5w$0^rCp1Iyyu|5LXYP=)onUty{Md-y}`* z(dJExJ@`NL19`Tj3 zV|zG&5Dy6HoO7oaieTe}3mb1)EZ}*$^T<4p4AY$LxQ{-H_7ltEm8e^Sxk6pEVk3^6 zbm2K3aLrYx%udz{_F|pewzDy$N55TRo%Fip*&l1o*`G=|bk;&f39Wqg3c3j7JF*9w z6DY({i6L}1ZVWs{4M31Ot`gux08ne2W5o8q)bp%h?~}_D|O!t zf}d;R+@Hy0?xH_yXr0WdDaENLj#Q+(9VG!CUK*o}Fx4UpYDXKK!Q^SUYIJ%_Qs;

|Uoq&lEW?_g?3-rposkge4XQmt(d~I}s{(Q>OUH3~* z6{7c2HDmxnHSGKg*=#D(xfCH&=1xl3oXja_xtOa0@uANt-}#|@)vSb#`+w@f9~*%)U|fC6I! z1kIBo7cH97G3!j(_1=#7D=f@`ltF+`i0l9V{~tVfaN)v*0|yRl z*sx*2f&~*MOlW9mC@3gMNJt0>2yk$4FfcGsP*4yM5CCeDVl$r{DK)Ap4~_T zavVHe978JRBqto;tB_g1Q^}~YSW2yw!=>O~l-Wau4#WEg>lq_{*fZNpCGTgLqWC$< ouI1nX4$;Jf2IEcBlx}k~yuBsBeW&@#44_#Ip00i_>zopr02j?c5dZ)H literal 0 HcmV?d00001 diff --git a/doc/html/form_20.png b/doc/html/form_20.png new file mode 100644 index 0000000000000000000000000000000000000000..b265383800ad6785c5c565bd57e814ad7c0a6499 GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^&Oj`{!VDz$|GO^;+Gx`S<%I#4)54d@!y_OE@vdviKQ` zLcjP5@9xG#OOHyy{i%$HnI~v&?2#8()*zF3^uPzsBV`lVg%nhIjyrzSmIi``DFzKw z988ZMno{#5DI)wbO*oD1~~@J!X1KV4`?%p+3_6_m)ybC zAYyztoo&X4YQyo literal 0 HcmV?d00001 diff --git a/doc/html/form_3.png b/doc/html/form_3.png new file mode 100644 index 0000000000000000000000000000000000000000..35b13316d1ff90f40ea8fa735e5653fdef2f5a18 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Q!VDx|Y8d4MDT4r?5ZC|z|37%};KGFq2M!$A zuwlc31q&ujn9$JBP*6~ikdP1%5a8h8U|?XNpr9ZiAOO@P#b`1gNHLZK`2{mLJiCzw zmdKI;Vst02Y2nUH||9 literal 0 HcmV?d00001 diff --git a/doc/html/form_4.png b/doc/html/form_4.png new file mode 100644 index 0000000000000000000000000000000000000000..e8f1ce8428492ddba3e779a17a253ce3ade69b95 GIT binary patch literal 1759 zcmV<51|a!~P)*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*NT}ebiRCt`tnQv@URTRL_``315U0+=!Xkyx6f?*O@2oNBemWYeS zY-#YO~E4ap*cV+9Zozjq!0cYG|%9^_k3_Atq3v+?;a>dPMD+dbJN z(4E-ODZcd%eMM&cHslsqbQ#lDtev3YX7J8Qd5 zaFhO=5@(-_fl7e$9EMd?n1_+*tvNd$l{E!g-HRW1M#7DD;gA zxQCz1nHQ_!eUBHxH;i%aECHv5L4|{mgK?nc^@NB6b~ZhN{-F2dpb0RJ%@T3Y8`-c= zf%8leoIc^%GA-g_(cwU{8a|ZK(@BEUCq$f{iqC)vZbgsQk4`%)WgE9eTu0*gvpC$* zJT^dZY*uV5)OgPfQ3Yrr5yx`M5_}U2*|p;4JuuE4wc+OUoh2qJRT#&7S0ipt-}Q@$ zO4TCy?xvI}S1pe3#DdwX#qgb2z{hf4wHUq=3izn&xsZUleAjYn9=;O``1laWEn4*5 zgRbvN1I>I7jRN;wX9O)?ms^*_C0vN{YRm+fhmu(|*!~`#`FM7gK0JGL)8_SbQ0Y5A z5*#zv){#$e2`hjl1N7hwwtTlue77z6f#^GUQ|Y^UbYEcR(xUGZ91~)PgbOADHu0U6 zj)}fAcc^`bPIT8?bwyml3iN#f4nFGzjB{tfpy<1&H>rJB7pZ2Lx!?e)2{~Rv#A(|J z&YfkZMc)k#s(qK)Qq3^m<=RM%XX@@JzZP-lY=UFH+frAf@BDwFyM~ntz4R`rStG7!FT;oYB{F3XBNaKq52%@jOBu0ybA=} zZHqqwAlxsS zXxEa}@tYi80RYl*SMBMxT*S#_ZtN+a@hoeYlc!2y4|n> z(z5_O&sOaxIL~m5TN2?m_C_ON8E2d*L01yzyt^H+MrK2|fa3gn3%&rs!I_iXlK4Uh z>jedlUsOMkB>UA@qEK@L9QZSj3OLuT2dIF~Cm!ol;F_j`Fiw)KH}rI-8a7RfxZcm# zwkHVA^ZQcQlKALCvwQUDY-=~Yj5RxOYXpb-TX9mr?zaL?3u&$;{~rSSZ*g<_4y5;) z3)tU*3t^5-QUgEcWkV0?4$|k(Mf-|fWBkjC?{Na zP`|uH`a7lXVB0)=$7c@;nJ+ck-zj~k|E%`iZ2LCjJGg76fWOZ?$L!TNlX3eyZOSUR ze#5?V7oooM9#;BJXy4ee7?()Zx0*8$#xGk8$A8fE8}eP$m=t}tQ-xzXqwO2>9nk+v zx#%m5;8$>WzNQPFqC3Hj)l&cybu^@fOhC*w2YIALB}@A?h-uF-u9 zT9fa@_D!>mv-IK!+2?Fr+a!%FSq+m>=)jCSte_zMzXv1n1*seu3h002ovPDHLkV1lZo BXf^-< literal 0 HcmV?d00001 diff --git a/doc/html/form_5.png b/doc/html/form_5.png new file mode 100644 index 0000000000000000000000000000000000000000..12857f26d427af43dd9c683da6f06570aa239a6e GIT binary patch literal 1814 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 literal 0 HcmV?d00001 diff --git a/doc/html/form_7.png b/doc/html/form_7.png new file mode 100644 index 0000000000000000000000000000000000000000..5dd84ef7cadad5a46709f49ad216ade3479d2e2b GIT binary patch literal 3464 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 ZzX4u|YHMW&a%KPk002ovPDHLkV1ls5PmTZp literal 0 HcmV?d00001 diff --git a/doc/html/form_9.png b/doc/html/form_9.png new file mode 100644 index 0000000000000000000000000000000000000000..d37bda2f3213fce350560aa94bca765c6b6f86e2 GIT binary patch literal 908 zcmV;719SX|P)*CP(VOHFfcG6ARrJB5C8xG8UZw)00001 zbW%=J06^y0W&i*K3Q0skRCt`tmQ85WU>L`rB<;Gc?bJG)5}2D zllXCoV{{&5ouCInnBP<{?PahY#&U4Nc5w$0^rCp1Iyyu|5LXYP=)onUty{Md-y}`* z(dJExJ@`NL19`Tj3 zV|zG&5Dy6HoO7oaieTe}3mb1)EZ}*$^T<4p4AY$LxQ{-H_7ltEm8e^Sxk6pEVk3^6 zbm2K3aLrYx%udz{_F|pewzDy$N55TRo%Fip*&l1o*`G=|bk;&f39Wqg3c3j7JF*9w z6DY({i6L}1ZVWs{4M31Ot`gux08ne2W5o8q)bp%h?~}_D|O!t zf}d;R+@Hy0?xH_yXr0WdDaENLj#Q+(9VG!CUK*o}Fx4UpYDXKK!Q^SUYIJ%_Qs;

|Uoq&lEW?_g?3-rposkge4XQmt(d~I}s{(Q>OUH3~* z6{7c2HDmxnHSGKg*=#D(xfCH&=1xl3oXja_xtOa0@uANt-}#|@)vSb#`+w@f9~*%)U|fC6I! z1kIBo7cH97G3!j(_1=#7 + +Compound Member Index + + + +

+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework Compound Members

+a | d | e | g | l | m | n | o | p | q | r | s | z | ~
+ +

+Here is a list of all class members with links to the class documentation for each member:

- a - +

+

- d - +

+

- e - +

+

- g - +

+

- l - +

+

- m - +

+

- n - +

+

- o - +

+

- p - +

+

- q - +

+

- r - +

+

- s - +

+

- z - +

+

- ~ - +

+
Generated on Thu Feb 27 13:46:20 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/globals.html b/doc/html/globals.html new file mode 100644 index 0000000..bf7735a --- /dev/null +++ b/doc/html/globals.html @@ -0,0 +1,130 @@ + + +File Member Index + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework File Members

+a | b | c | d | e | g | m | n | o | p | q | r | s | t | v | y
+ +

+Here is a list of all file members with links to the files they belong to:

- a - +

+

- b - +

+

- c - +

+

- d - +

+

- e - +

+

- g - +

+

- m - +

+

- n - +

+

- o - +

+

- p - +

+

- q - +

+

- r - +

+

- s - +

+

- t - +

+

- v - +

+

- y - +

+
Generated on Thu Feb 27 13:46:26 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Attitude.html b/doc/html/group__Attitude.html new file mode 100644 index 0000000..7586875 --- /dev/null +++ b/doc/html/group__Attitude.html @@ -0,0 +1,362 @@ + + +Spacecraft Attitude + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Attitude
+ +[Spacecraft Framework] +

+ + + + + + + + + + + + + + +

Functions

Rotation GetAttitude (AttitudeFrame _Frame)
Matrix GetAngularVelocity ()
Matrix GetAngularAcceleration ()
AttitudeFrame GetFrame ()
void SetFrame (AttitudeFrame _Frame)
void SetAttitude (Rotation _Attitude, AttitudeFrame _Frame=NO_FRAME)
void SetAngularVelocity (Matrix _AngularVelocity)
void SetAngularAcceleration (Matrix _AngularAcceleration)

Variables

Rotation GetAttitude ()
Rotation GetAttitudeBO ()
Rotation GetAttitudeBI ()
+

Detailed Description

+Spacecraft attitude inspectors and mutators

Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix Spacecraft::GetAngularAcceleration   [inherited]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
Matrix Spacecraft::GetAngularVelocity   [inherited]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
Rotation Spacecraft::GetAttitude AttitudeFrame   _Frame [inherited]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
AttitudeFrame Spacecraft::GetFrame   [inherited]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetAngularAcceleration Matrix   _AngularAcceleration [inherited]
+
+ + + + + +
+   + + +

+Sets the spacecraft angular acceleration. Sets the current angular acceleration of the spacecraft given an angular acceleration matrix.

Parameters:
+ + +
_AngularAcceleration  +(double) - (3x1) matrix of angular accelerations (rad/s^2)
+
+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetAngularVelocity Matrix   _AngularVelocity [inherited]
+
+ + + + + +
+   + + +

+Sets the spacecraft angular velocity. Sets the current angular velocity of the spacecraft given an angular velocity matrix.

Parameters:
+ + +
_AngularVelocity  +(double) - (3x1) matrix of angular velocities (rad/s)
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Spacecraft::SetAttitude Rotation   _Attitude,
AttitudeFrame   _Frame = NO_FRAME
[inherited]
+
+ + + + + +
+   + + +

+Set the spacecraft attitude. Sets the current attitude of the spacecraft given a rotation and reference frame.

Parameters:
+ + + +
_Attitude  +(Rotation) - attitude rotation ()
_Frame  +(AttitudeFrame) - integer describing specified reference frame of attitude
+
+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetFrame AttitudeFrame   _Frame [inherited]
+
+ + + + + +
+   + + +

+Set the spacecraft attitude frame. Sets the current attitude reference frame of the spacecraft. Changes the stored frame and equations of motion. Does not change change current attitude in reference frame to new attitude in specified frame.

Parameters:
+ + +
_Frame  +(AttitudeFrame) - integer describing specified reference frame of attitude
+
+


Variable Documentation

+

+ + + + +
+ + +
Rotation Spacecraft::GetAttitude [inherited] +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
Rotation Spacecraft::GetAttitudeBI [inherited] +
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + +
Rotation Spacecraft::GetAttitudeBO [inherited] +
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 13 11:19:15 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__AttitudeControl.html b/doc/html/group__AttitudeControl.html new file mode 100644 index 0000000..1b68e2a --- /dev/null +++ b/doc/html/group__AttitudeControl.html @@ -0,0 +1,118 @@ + + +Attitude Control + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Attitude Control
+ +[Spacecraft Framework] +

+ + + + + +

Functions

Matrix GetControlTorques ()
void SetMinMaxControlTorque (Matrix _MinMax)
void SetControlTorques (const Matrix &_ControlTorques)
+

Detailed Description

+The equations of motion (EOM) define the time dynamics of the spacecraft

Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix Spacecraft::GetControlTorques   [inherited]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetControlTorques const Matrix  _ControlTorques [inherited]
+
+ + + + + +
+   + + +

+Set control torques. Sets the control torques with respect to the stored axes.

Parameters:
+ + +
_ControlTorques  +(Matrix<double>) - (m_numControls x 1) matrix of spacecraft control torques (Nm)
+
+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetMinMaxControlTorque Matrix   _MinMax [inherited]
+
+ + + + + +
+   + + +

+Sets the minimum and maximum control torques for all control inputs. Sets the minimum and maximum control torques for all control inputs.

Returns :
+(Matrix<double>) - (m_numControls x 2) each row corresponds to (min,max) control input for each control (Nm)
+


Generated on Thu Feb 13 11:19:15 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__AttitudeRepresentation.html b/doc/html/group__AttitudeRepresentation.html new file mode 100644 index 0000000..2eed6a9 --- /dev/null +++ b/doc/html/group__AttitudeRepresentation.html @@ -0,0 +1,23 @@ + + +Kinematic Toolbox + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Kinematic Toolbox

+ + + + + + +

Modules

Direction Cosine Matrix
Modified Rodriguez Parameters
Quaternion Attitude Representation
Rotation
+

Detailed Description

+The Kinematics Toolbox is a collection of attitude representation class definitions that are meant to assist in the implementation of spacecraft analysis and operation code.
Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Constructors.html b/doc/html/group__Constructors.html new file mode 100644 index 0000000..fcdb414 --- /dev/null +++ b/doc/html/group__Constructors.html @@ -0,0 +1,151 @@ + + +Constructors + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Constructors
+ +[Spacecraft Framework] +

+ + + + + +

Functions

 Spacecraft ()
 Spacecraft (Quaternion AttitudeQuaternion, Matrix AngularVelocity, Matrix AngularAcceleration, Matrix InertialPosition, Matrix InertialVelocity)
virtual ~Spacecraft ()
+

Detailed Description

+Spacecraft constructors for initial creation and initialization of spacecraft objects.

Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Spacecraft::Spacecraft Quaternion   AttitudeQuaternion,
Matrix   AngularVelocity,
Matrix   AngularAcceleration,
Matrix   InertialPosition,
Matrix   InertialVelocity
[inherited]
+
+ + + + + +
+   + + +

+Spacecraft Constructor. Creates a spacecraft given an initial attitude, anglular velocity & acceleration, position and velocity.

Parameters:
+ + + + + + +
AttitudeQuaternion  +(double): initial attitude of spacecraft in the Body->Orbital reference frame
AngularVelocity  +(double): initial angular velocity of spacecraft (rad/s)
AngularAcceleration  +(double): initial angular acceleration of spacecraft (rad/s^2)
InertialPosition  +(double): initial position of spacecraft in ECI reference frame (m)
InertialVelocity  +(double): initial velocity of spacecraft in ECI reference frame (m)
+
+

+ + + + +
+ + + + + + + + + +
Spacecraft::Spacecraft   [inherited]
+
+ + + + + +
+   + + +

+Default Constructor. Creates a satellite with no initial attitude or position.

+

+ + + + +
+ + + + + + + + + +
Spacecraft::~Spacecraft   [virtual, inherited]
+
+ + + + + +
+   + + +

+Default Deconstructor.

+


Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__DCM.html b/doc/html/group__DCM.html new file mode 100644 index 0000000..6b83d03 --- /dev/null +++ b/doc/html/group__DCM.html @@ -0,0 +1,23 @@ + + +Direction Cosine Matrix + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Direction Cosine Matrix
+ +[Kinematic Toolbox] +

+ + + +

Compounds

class  DirectionCosineMatrix
+

Detailed Description

+The 3x3 direction cosine matrix attitude representation
Generated on Tue Feb 11 14:21:56 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__DCMOperators.html b/doc/html/group__DCMOperators.html new file mode 100644 index 0000000..3ce5485 --- /dev/null +++ b/doc/html/group__DCMOperators.html @@ -0,0 +1,90 @@ + + +DCM Operators + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

DCM Operators

+ + + + +

Functions

DCM operator+ (const DCM &_DCM2) const
DCM operator- (const DCM &_DCM2) const
+

Detailed Description

+Set of overloaded operators for performation unary and binary operations on Direction Cosine Matrices.

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
DCM DirectionCosineMatrix::operator+ const DCM &   _DCM2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two DCMs.

Parameters:
+ + +
_DCM2  +DCM to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
DCM DirectionCosineMatrix::operator- const DCM &   _DCM2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two DCMs.

Parameters:
+ + +
_DCM2  +DCM to be differenced with.
+
+


Generated on Tue Jan 28 13:49:26 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__DirectionCosineMatrix.html b/doc/html/group__DirectionCosineMatrix.html new file mode 100644 index 0000000..16e546e --- /dev/null +++ b/doc/html/group__DirectionCosineMatrix.html @@ -0,0 +1,130 @@ + + +Direction Cosine Matrix + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Direction Cosine Matrix
+ +[Kinematic Toolbox] +

+ + + + + + + +

Compounds

class  DirectionCosineMatrix

Functions

DirectionCosineMatrix R1 (const double &_Angle)
DirectionCosineMatrix R2 (const double &_Angle)
DirectionCosineMatrix R3 (const double &_Angle)
+

Detailed Description

+The 3x3 direction cosine matrix attitude representation

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix R1 const double &   _Angle
+
+ + + + + +
+   + + +

+Calculates the principal rotation of the angle about the 1-axis.

Parameters:
+ + +
_Angle  +Angle of Rotation [rad].
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix R2 const double &   _Angle
+
+ + + + + +
+   + + +

+Calculates the principal rotation of the angle about the 2-axis.

Parameters:
+ + +
_Angle  +Angle of Rotation [rad].
+
+

+ + + + +
+ + + + + + + + + + +
DirectionCosineMatrix R3 const double &   _Angle
+
+ + + + + +
+   + + +

+Calculates the principal rotation of the angle about the 3-axis.

Parameters:
+ + +
_Angle  +Angle of Rotation [rad].
+
+


Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__EOM.html b/doc/html/group__EOM.html new file mode 100644 index 0000000..7df7023 --- /dev/null +++ b/doc/html/group__EOM.html @@ -0,0 +1,188 @@ + + +Equations of Motion + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Equations of Motion
+ +[Spacecraft Framework] +

+ + + + + +

Functions

Matrix EOM_bi (double time, Matrix stateVariables, Matrix constantsInput)
Matrix EOM_bo (double time, Matrix stateVariables, Matrix constantsInput)
Matrix EOM_bo_Linear (double time, Matrix stateVariables, Matrix constantsInput)
+

Detailed Description

+The equations of motion (EOM) define the time dynamics of the spacecraft

Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrix Spacecraft::EOM_bi double   time,
Matrix   stateVariables,
Matrix   constantsInput
[static, inherited]
+
+ + + + + +
+   + + +

+Equations of Motion - Body to Inertial Coordinates. Equations of Motion - Body to Inertial Coordinates.

Parameters:
+ + + + +
time  +(double): initial time of integration, measured since epoch (s)
stateVariables  +(double): (7x1) matrix of initial conditions [q1,q2,q3,q4,w1,w2,w3]
constantsInput  +(double): (mxn) matrix of constants of integration
+
Returns :
+(double) - (7 x 1) matrix of time derivatives of state variables [q1_dot,q2_dot,q3_dot,q4_dot,w1_dot,w2_dot,w3_dot]
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrix Spacecraft::EOM_bo double   time,
Matrix   stateVariables,
Matrix   constantsInput
[static, inherited]
+
+ + + + + +
+   + + +

+Equations of Motion - Body to Orbital Coordinates. Equations of Motion - Body to Orbital Coordinates.

Parameters:
+ + + + +
time  +(double): initial time of integration, measured since epoch (s)
stateVariables  +(double): (7x1) matrix of initial conditions [q1,q2,q3,q4,w1,w2,w3]
constantsInput  +(double): (mxn) matrix of constants of integration
+
Returns :
+(double) - (7 x 1) matrix of time derivatives of state variables [q1_dot,q2_dot,q3_dot,q4_dot,w1_dot,w2_dot,w3_dot]
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrix Spacecraft::EOM_bo_Linear double   time,
Matrix   stateVariables,
Matrix   constantsInput
[static, inherited]
+
+ + + + + +
+   + + +

+Equations of Motion - Linearized Body to Orbital Coordinates. Equations of Motion - Linearized Body to Orbital Coordinates.

Parameters:
+ + + + +
time  +(double): initial time of integration, measured since epoch (s)
stateVariables  +(double): (7x1) matrix of initial conditions [q1,q2,q3,q4,w1,w2,w3]
constantsInput  +(double): (mxn) matrix of constants of integration
+
Returns :
+(double) - (7 x 1) matrix of time derivatives of state variables [q1_dot,q2_dot,q3_dot,q4_dot,w1_dot,w2_dot,w3_dot]
+


Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__FileAccess.html b/doc/html/group__FileAccess.html new file mode 100644 index 0000000..6ad2fe1 --- /dev/null +++ b/doc/html/group__FileAccess.html @@ -0,0 +1,180 @@ + + +File Access + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

File Access
+ +[Spacecraft Framework] +

+ + + + + + + + + + + +

Functions

void SetName (string _Name)
void OutputSTKAttitude ()
 Saves the spacecraft attitude history in an STK attitude file (saved as 'm_Name'.a).

void LoadFromFile ()
 Loads the spacecraft parameters from a file - need to set the spacecraft name first.

void SaveToFile ()
 Saves all the spacecraft parameters to file based on the spacecraft name (Not Complete).


Variables

Rotation GetOrbitalInertialRotation ()
+

Detailed Description

+Spacecraft file access

Function Documentation

+

+ + + + +
+ + + + + + + + + +
void Spacecraft::LoadFromFile   [inherited]
+
+ + + + + +
+   + + +

+Loads the spacecraft parameters from a file - need to set the spacecraft name first. +

+

+

+ + + + +
+ + + + + + + + + +
void Spacecraft::OutputSTKAttitude   [inherited]
+
+ + + + + +
+   + + +

+Saves the spacecraft attitude history in an STK attitude file (saved as 'm_Name'.a). +

+

+

+ + + + +
+ + + + + + + + + +
void Spacecraft::SaveToFile   [inherited]
+
+ + + + + +
+   + + +

+Saves all the spacecraft parameters to file based on the spacecraft name (Not Complete). +

+

+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetName string   _Name [inherited]
+
+ + + + + +
+   + + +

+Sets the spacecraft's name. Sets the spacecraft's name.

Parameters:
+ + +
_Name  +(string) - spacecraft name
+
+


Variable Documentation

+

+ + + + +
+ + +
Rotation Spacecraft::GetOrbitalInertialRotation [inherited] +
+
+ + + + + +
+   + + +

+Gets the inertial to orbital rotation (Not Complete). Gets the inertial to orbital rotation (Not Complete).

Returns :
+Rotation - Roi
+


Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__History.html b/doc/html/group__History.html new file mode 100644 index 0000000..1dd9138 --- /dev/null +++ b/doc/html/group__History.html @@ -0,0 +1,225 @@ + + +History + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

History
+ +[Spacecraft Framework] +

+ + + + + + + +

Functions

void SetNumHistorySteps (int _numSteps)
void ResetFlightHistory ()
Matrix GetFlightHistory (double _beginTime=-1, double _endTime=-1, AttitudeFrame _Frame=NO_FRAME)
Matrix GetFlightHistory (AttitudeFrame _Frame)
Matrix GetControlHistory (double _beginTime=-1, double _endTime=-1)
+

Detailed Description

+Spacecraft flight history

Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Matrix Spacecraft::GetControlHistory double   _beginTime = -1,
double   _endTime = -1
[inherited]
+
+ + + + + +
+   + + +

+Returns the attitude control history profile (Not Complete). Returns the attitude control history profile between initial and final times (Not Complete).

Parameters:
+ + + +
_beginTime  +(double) - initial time of integration, measured from seconds since epoch (s).
_endTime  +(double) - final time of integration, measured from seconds since epoch (s).
+
Returns :
+double - (n x (time + m_numControls)) matrix of time history of attitude controls
+

+ + + + +
+ + + + + + + + + + +
Matrix Spacecraft::GetFlightHistory AttitudeFrame   _Frame [inherited]
+
+ + + + + +
+   + + +

+Returns the time history of the spacecraft attitude (Not Complete). Returns the entire time history of the spacecraft attitude with respect to appropriate frame (Not Complete).

Parameters:
+ + +
_Frame  +(AttitudeFrame) - desired attitude frame of returned history ().
+
Returns :
+double - (n x 8) matrix of time history of attitude states. [time,q1,q2,q3,q4,w1,w2,w3] (units as before)
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Matrix Spacecraft::GetFlightHistory double   _beginTime = -1,
double   _endTime = -1,
AttitudeFrame   _Frame = NO_FRAME
[inherited]
+
+ + + + + +
+   + + +

+Returns the time history of the spacecraft attitude (Not Complete). Returns the time history of the spacecraft attitude from an initial to final time (Not Complete).

Parameters:
+ + + + +
_beginTime  +(double) - initial time of integration, measured from seconds since epoch (s).
_endTime  +(double) - final time of integration, measured from seconds since epoch (s).
_Frame  +(AttitudeFrame) - desired attitude frame of returned history ().
+
Returns :
+double - (n x 8) matrix of time history of attitude states. [time,q1,q2,q3,q4,w1,w2,w3] (units as before)
+

+ + + + +
+ + + + + + + + + +
void Spacecraft::ResetFlightHistory   [inherited]
+
+ + + + + +
+   + + +

+Resets the flight history to initial conditions (Not Complete). Resets the flight history to initial conditions (Not Complete).

+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetNumHistorySteps int   _numSteps [inherited]
+
+ + + + + +
+   + + +

+Sets the expected number of history steps. Sets the total projected number of history steps - only needed to speed up propagation.

Parameters:
+ + +
_numSteps  +(int) - predicted number of steps that will be stored in the final flight history.
+
+


Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__MRP.html b/doc/html/group__MRP.html new file mode 100644 index 0000000..5b40281 --- /dev/null +++ b/doc/html/group__MRP.html @@ -0,0 +1,23 @@ + + +Modified Rodriguez Parameters + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Modified Rodriguez Parameters
+ +[Kinematic Toolbox] +

+ + + +

Compounds

class  ModifiedRodriguezParameters
+

Detailed Description

+The 3x1 Modified Rodriguez Parameters attitude representation
Generated on Tue Feb 11 14:21:56 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__MRPOperators.html b/doc/html/group__MRPOperators.html new file mode 100644 index 0000000..9b276bd --- /dev/null +++ b/doc/html/group__MRPOperators.html @@ -0,0 +1,90 @@ + + +MRP Operators + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

MRP Operators

+ + + + +

Functions

MRP operator+ (const DCM &_MRP2) const
MRP operator- (const MRP &_MRP2) const
+

Detailed Description

+Set of overloaded operators for performation unary and binary operations on MRPs.

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
MRP ModifiedRodriguezParameters::operator+ const DCM &   _MRP2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two MRP vectors.

Parameters:
+ + +
_MRP2  +MRP vector to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
MRP ModifiedRodriguezParameters::operator- const MRP &   _MRP2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two MRP vectors.

Parameters:
+ + +
_MRP2  +MRP vector to be differenced with.
+
+


Generated on Tue Jan 28 13:49:26 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__ModifiedRodriguezParameters.html b/doc/html/group__ModifiedRodriguezParameters.html new file mode 100644 index 0000000..7ba0b0b --- /dev/null +++ b/doc/html/group__ModifiedRodriguezParameters.html @@ -0,0 +1,86 @@ + + +Modified Rodriguez Parameters + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Modified Rodriguez Parameters
+ +[Kinematic Toolbox] +

+ + + + + + + +

Compounds

class  ModifiedRodriguezParameters

Functions

void Set (const Quaternion &_qIN)

Variables

ModifiedRodriguezParameters ShadowSet ()
+

Detailed Description

+The 3x1 Modified Rodriguez Parameters attitude representation

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
void ModifiedRodriguezParameters::Set const Quaternion  _qIN [inherited]
+
+ + + + + +
+   + + +

+Set the MRPs from a converted quaternion.

Parameters:
+ + +
_qIN  +4x1 quaternion to be converted
+
+


Variable Documentation

+

+ + + + +
+ + +
ModifiedRodriguezParameters ModifiedRodriguezParameters::ShadowSet [inherited] +
+
+ + + + + +
+   + + +

+Calculates and returns the MRP shadow set.

Returns :
+MRP shadow set (3x1).
+


Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Orbital.html b/doc/html/group__Orbital.html new file mode 100644 index 0000000..a552d7d --- /dev/null +++ b/doc/html/group__Orbital.html @@ -0,0 +1,191 @@ + + +Orbital Toolbox + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Orbital Toolbox
+ +[Spacecraft Framework] +

+ + + + + + + + + +

Compounds

class  Orbit

Functions

Matrix GetPosition ()
Matrix GetVelocity ()
double GetOrbitalAngularVelocity ()
double GetInclination ()
void SetPositionVelocity (Matrix _InertialPosition, Matrix _InertialVelocity)
+

Detailed Description

+The Orbital Toolbox is an orbit representation class that is meant to assist in the implementation of spacecraft analysis and operation code.

Function Documentation

+

+ + + + +
+ + + + + + + + + +
double Orbit::GetInclination   [inherited]
+
+ + + + + +
+   + + +

+Get current spacecraft orbital inclination. Returns the current inclination of the spacecraft orbit.

Returns :
+(double) - orbital inclination (rad).
+

+ + + + +
+ + + + + + + + + +
double Orbit::GetOrbitalAngularVelocity   [inherited]
+
+ + + + + +
+   + + +

+Get current spacecraft orbital angular velocity. Returns the current orbital angular velocity of the spacecraft.

Returns :
+(double) - orbital angular velocity (rad/s).
+

+ + + + +
+ + + + + + + + + +
Matrix Orbit::GetPosition   [inherited]
+
+ + + + + +
+   + + +

+Get current spacecraft cartesian position. Returns the current position of the spacecraft with respect to the stored orbital frame in cartesian coordinates.

Returns :
+(Matrix<double>) - (3x1) matrix of orbital position coordinates (x,y,z) w/ respect to orbital reference frame in cartesian coordinates (m).
+

+ + + + +
+ + + + + + + + + +
Matrix Orbit::GetVelocity   [inherited]
+
+ + + + + +
+   + + +

+Get current spacecraft velocity. Returns the current velocity of the spacecraft with respect to the stored orbital frame.

Returns :
+(Matrix<double>) - (3x1) matrix of orbital velocity coordinates (u,v,w) w/ respect to orbital reference frame in cartesian coordinates(m/s).
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Orbit::SetPositionVelocity Matrix   _InertialPosition,
Matrix   _InertialVelocity
[inherited]
+
+ + + + + +
+   + + +

+Set current spacecraft position and velocity. Set current spacecraft position and velocity in cartesian coordinates.

Parameters:
+ + + +
_InertialPosition  +(Matrix<double>) - (3 x 1) matrix of orbital position coordinates (x,y,z) w/ respect to orbital reference frame in cartesian coordinates (m).
_InertialVelocity  +(Matrix<double>) - (3 x 1) matrix of orbital velocity coordinates (u,v,w) w/ respect to orbital reference frame in cartesian coordinates(m/s).
+
+


Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__OrbitalControl.html b/doc/html/group__OrbitalControl.html new file mode 100644 index 0000000..2a3edfb --- /dev/null +++ b/doc/html/group__OrbitalControl.html @@ -0,0 +1,58 @@ + + +Orbital Control + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Orbital Control
+ +[Spacecraft Framework] +

+ + + +

Functions

void SetControlForces (Matrix _ControlForces)
+

Detailed Description

+Spacecraft orbital control inspectors and mutators

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
void Orbit::SetControlForces Matrix   _ControlForces [inherited]
+
+ + + + + +
+   + + +

+Sets the orbital control forces of the spacecraft. Sets the orbital control forces of the spacecraft in cartesian coordinates.

Parameters:
+ + +
_ControlForces  +(Matrix<double>) - (3x1) matrix of control forces in (x,y,z) body axes (N).
+
+


Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Physical.html b/doc/html/group__Physical.html new file mode 100644 index 0000000..07ea01c --- /dev/null +++ b/doc/html/group__Physical.html @@ -0,0 +1,118 @@ + + +Physical + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Physical
+ +[Spacecraft Framework] +

+ + + + + +

Functions

Matrix GetMomentsInertia ()
Matrix GetSpacecraftTorques ()
void SetMomentsInertia (Matrix _momentsInertia)
+

Detailed Description

+Spacecraft physical parameters

Function Documentation

+

+ + + + +
+ + + + + + + + + +
Matrix Spacecraft::GetMomentsInertia   [inherited]
+
+ + + + + +
+   + + +

+Returns the moments of inertia of the spacecraft. Returns the moments of inertia of the spacecraft.

Returns :
+Matrix<double> - (3x3) matrix of spacecraft moments of inertia (kg-m^2).
+

+ + + + +
+ + + + + + + + + +
Matrix Spacecraft::GetSpacecraftTorques   [inherited]
+
+ + + + + +
+   + + +

+Returns the external spacecraft torques. Returns the external spacecraft torques.

Returns :
+Matrix<double> - (3x1) matrix of external torques along primary body axes (N-m).
+

+ + + + +
+ + + + + + + + + + +
void Spacecraft::SetMomentsInertia Matrix   _momentsInertia [inherited]
+
+ + + + + +
+   + + +

+Sets the moments of inertia of the spacecraft. Sets the moments of inertia of the spacecraft.

Parameters:
+ + +
_momentsInertia  +(Matrix<double>) - (3x3) matrix of spacecraft moments of inertia (kg-m^2).
+
+


Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Propagators.html b/doc/html/group__Propagators.html new file mode 100644 index 0000000..ca8cdea --- /dev/null +++ b/doc/html/group__Propagators.html @@ -0,0 +1,78 @@ + + +Propagators + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Propagators
+ +[Spacecraft Framework] +

+ + + +

Functions

void Propagate (double StartTime, double EndTime, int numSteps=100)
+

Detailed Description

+The propagators integrate the spacecraft dynamics through time

Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void Spacecraft::Propagate double   StartTime,
double   EndTime,
int   numSteps = 100
[inherited]
+
+ + + + + +
+   + + +

+Propagation through time. Propagates the satellites attitude dynamics through time based on reference frame.

Parameters:
+ + + + +
StartTime  +(double): initial time of integration, measured since epoch (s)
EndTime  +(double): final time of integration, measured since epoch (s)
numSteps  +(double): number of integration steps to use
+
Returns :
+(double) - (n x 8) matrix of time history of attitude states [time,q1,q2,q3,q4,w1,w2,w3] (units as before)
+


Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Quaternion.html b/doc/html/group__Quaternion.html new file mode 100644 index 0000000..04420a7 --- /dev/null +++ b/doc/html/group__Quaternion.html @@ -0,0 +1,26 @@ + + +Quaternion Attitude Representation + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Quaternion Attitude Representation
+ +[Kinematic Toolbox] +

+ + + +

Compounds

class  Quaternion
+

Detailed Description

+The non-singular, redundant Euler parameter (quaternion) vector

+ +

+ for i=1,2,3


Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__QuaternionOperators.html b/doc/html/group__QuaternionOperators.html new file mode 100644 index 0000000..8d9ac05 --- /dev/null +++ b/doc/html/group__QuaternionOperators.html @@ -0,0 +1,90 @@ + + +Quaternion Operators + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Quaternion Operators

+ + + + +

Functions

Quaternion operator+ (const Quaternion &_quat2) const
Quaternion operator- (const Quaternion &_quat2) const
+

Detailed Description

+Set of overloaded operators for performation unary and binary operations on quaternions.

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
Quaternion Quaternion::operator+ const Quaternion &   _quat2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two quaternions.

Parameters:
+ + +
_quat2  +Quaternion to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
Quaternion Quaternion::operator- const Quaternion &   _quat2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two quaternions.

Parameters:
+ + +
_quat2  +Quaternion to be differenced with.
+
+


Generated on Tue Jan 28 13:49:25 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Rotation.html b/doc/html/group__Rotation.html new file mode 100644 index 0000000..d42e6cf --- /dev/null +++ b/doc/html/group__Rotation.html @@ -0,0 +1,23 @@ + + +Rotation + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation
+ +[Kinematic Toolbox] +

+ + + +

Compounds

class  Rotation
+

Detailed Description

+A generalized rotation class to represent any attitude coordinate transformation
Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__RotationInspectors.html b/doc/html/group__RotationInspectors.html new file mode 100644 index 0000000..4c0b8fc --- /dev/null +++ b/doc/html/group__RotationInspectors.html @@ -0,0 +1,176 @@ + + +Rotation Inspectors + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation Inspectors

+ + + + + + + + +

Functions

void GetAxisAngle (Matrix &_EulerAxis, double &_EulerAngle) const
Matrix GetEulerAngles (int _Sequence)

Variables

Quaternion GetQuaternion () const
ModifiedRodriguezParameters GetMRP () const
DirectionCosineMatrix GetDCM () const
+

Detailed Description

+Set of member functions to retrieve various representations of a rotation.

Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Rotation::GetAxisAngle Matrix  _EulerAxis,
double &   _EulerAngle
const [inherited]
+
+ + + + + +
+   + + +

+Return the Euler Axis and Angle form of the attitude transformation.

Parameters:
+ + + +
_EulerAxis  +3x1 Euler Axis to be returned.
_EulerAngle  +Euler angle of rotation [rad].
+
+

+ + + + +
+ + + + + + + + + + +
Matrix Rotation::GetEulerAngles int   _Sequence [inherited]
+
+ + + + + +
+   + + +

+Return the Euler angles from the rotation representation.

Parameters:
+ + +
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
Returns :
+_Angles 3x1 matrix of euler angles.
+


Variable Documentation

+

+ + + + +
+ + +
DirectionCosineMatrix Rotation::GetDCM [inherited] +
+
+ + + + + +
+   + + +

+Return the Direction Cosine Matrix (DCM) form of the attitude transformation.

Returns :
+3x3 Direction Cosine Matrix (DCM).
+

+ + + + +
+ + +
ModifiedRodriguezParameters Rotation::GetMRP [inherited] +
+
+ + + + + +
+   + + +

+Return the Modified Rodriguez Parameters vector form of the attitude transformation.

Returns :
+3x1 MRP vector.
+

+ + + + +
+ + +
Quaternion Rotation::GetQuaternion [inherited] +
+
+ + + + + +
+   + + +

+Return the quaternion form of the attitude transformation.

Returns :
+4x1 quaternion.
+


Generated on Tue Jan 28 13:49:26 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__RotationMutators.html b/doc/html/group__RotationMutators.html new file mode 100644 index 0000000..4981947 --- /dev/null +++ b/doc/html/group__RotationMutators.html @@ -0,0 +1,252 @@ + + +Rotation Mutators + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation Mutators

+ + + + + + + + +

Functions

void Set (Matrix _inMatrix)
void Set (const DirectionCosineMatrix &_DCM)
void Set (const Matrix &_Angles, int _Sequence)
void Set (const Matrix _Axis, double _Angle)
void Set (const ModifiedRodriguezParameters &_MRP)
void Set (const Quaternion &_quat)
+

Detailed Description

+Set of member functions to manipulate the rotation representation.

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set const Quaternion  _quat [inherited]
+
+ + + + + +
+   + + +

+Set the Rotation from a converted quaternion.

Parameters:
+ + +
_quat  +4x1 quaternion to set the Rotation.
+
+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set const ModifiedRodriguezParameters  _MRP [inherited]
+
+ + + + + +
+   + + +

+Set the Rotation from a converted vector of MRP.

Parameters:
+ + +
_MRP  +3x1 vector of Modified Rodriguez Parameters to set the Rotation.
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Rotation::Set const Matrix   _Axis,
double   _Angle
[inherited]
+
+ + + + + +
+   + + +

+Set the Rotation from a converted Euler Axis and Angle set.

Parameters:
+ + + +
_Axis  +3x1 Euler Axis.
_Angle  +Angle rotation about axis [rad].
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void Rotation::Set const Matrix  _Angles,
int   _Sequence
[inherited]
+
+ + + + + +
+   + + +

+Set the Rotation from an euler angle sequence.

Parameters:
+ + + +
_Angles  +3x1 matrix of euler angles.
_Sequence  +Euler angle rotation sequence. (ie 123, 213, 313, 321, etc).
+
+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set const DirectionCosineMatrix  _DCM [inherited]
+
+ + + + + +
+   + + +

+Set the Rotation from a converted DCM.

Parameters:
+ + +
_DCM  +3x3 matrix of Direction Cosine Matrix (DCM) values.
+
+

+ + + + +
+ + + + + + + + + + +
void Rotation::Set Matrix   _inMatrix [inherited]
+
+ + + + + +
+   + + +

+Set the Rotation from a converted DCM.

Parameters:
+ + +
_inMatrix  +3x3 matrix of Direction Cosine Matrix (DCM) values.
+
+


Generated on Tue Jan 28 13:49:26 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__RotationOperators.html b/doc/html/group__RotationOperators.html new file mode 100644 index 0000000..69467ab --- /dev/null +++ b/doc/html/group__RotationOperators.html @@ -0,0 +1,151 @@ + + +Rotation Operators + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Rotation Operators

+ + + + + + +

Functions

Rotation Rotation::operator * (const Rotation &_rot2) const
Rotation Rotation::operator~ () const
Rotation Rotation::operator+ (const Rotation &_rot2) const
Rotation Rotation::operator- (const Rotation &_rot2) const
+

Detailed Description

+Set of overloaded operators for performation unary and binary operations on rotations.

Function Documentation

+

+ + + + +
+ + + + + + + + + + +
Rotation Rotation::Rotation::operator * const Rotation &   _rot2 const [inherited]
+
+ + + + + +
+   + + +

+Multiply the rotation matrices together.

Returns :
+3x3 Direction Cosine Matrix (DCM).
+

+ + + + +
+ + + + + + + + + + +
Rotation Rotation::Rotation::operator+ const Rotation &   _rot2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the successive rotation from the summation of two rotations.

Parameters:
+ + +
_rot2  +Rotation to be summed with.
+
+

+ + + + +
+ + + + + + + + + + +
Rotation Rotation::Rotation::operator- const Rotation &   _rot2 const [inherited]
+
+ + + + + +
+   + + +

+Determine the relative rotation from the difference of two rotations.

Parameters:
+ + +
_rot2  +Rotation to be differenced with.
+
+

+ + + + +
+ + + + + + + + + +
Rotation Rotation::Rotation::operator~   const [inherited]
+
+ + + + + +
+   + + +

+Take the inverse of the rotation matrix.

Returns :
+3x3 Direction Cosine Matrix (DCM).
+


Generated on Tue Jan 28 13:49:26 2003 for Spacecraft Simulation Toolbox by + +doxygen1.2.17
+ + diff --git a/doc/html/group__SpacecraftFramework.html b/doc/html/group__SpacecraftFramework.html new file mode 100644 index 0000000..82a451a --- /dev/null +++ b/doc/html/group__SpacecraftFramework.html @@ -0,0 +1,29 @@ + + +Spacecraft Framework + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Framework

+ + + + + + + + + + + + +

Modules

Orbital Toolbox
Orbital Control
Constructors
Propagators
Equations of Motion
Physical
History
File Access

Compounds

class  Spacecraft
+

Detailed Description

+Spacecraft Framework.
Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Trigonometry.html b/doc/html/group__Trigonometry.html new file mode 100644 index 0000000..d420939 --- /dev/null +++ b/doc/html/group__Trigonometry.html @@ -0,0 +1,406 @@ + + +Trigonometry Routines + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Trigonometry Routines

+ + + + + + + + + + + + + +

Typedefs

typedef double Angle

Functions

Angle DMS2Deg (double _Degrees, double _Minutes, double _Seconds)
void Deg2DMS (Angle _Angle, double &Degrees, double &Minutes, double &Seconds)
Angle DMS2Rad (double _Degrees, double _Minutes, double _Seconds)
Angle Deg2Rad (Angle _Degrees)
void Rad2DMS (Angle _Radians, double &Degrees, double &Minutes, double &Seconds)
Angle Rad2Deg (Angle _Radians)
double atanh (double z)

Variables

const double PI = 3.14159
+

Detailed Description

+Toolbox of Trigonometry routines useful for spacecraft operations.

Typedef Documentation

+

+ + + + +
+ + +
typedef double Angle +
+
+ + + + + +
+   + + +

+

+


Function Documentation

+

+ + + + +
+ + + + + + + + + + +
double atanh double   z [inline]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Deg2DMS Angle   _Angle,
double &   Degrees,
double &   Minutes,
double &   Seconds
+
+ + + + + +
+   + + +

+Converts an angle from a single quantity in degrees and fractions of a degree to Degrees, Minutes, Seconds (^o,','').

Parameters:
+ + + + + +
_Angle  +in degrees (with decimal part).
_Degrees  +Number of degrees in angle (^o).
_Minutes  +Number of minutes in angle (').
_Seconds  +Number of seconds in angle ('').
+
+

+ + + + +
+ + + + + + + + + + +
Angle Deg2Rad Angle   _Degrees
+
+ + + + + +
+   + + +

+Converts an angle from Degrees to radians.

Parameters:
+ + +
_Degrees  +Angle to be converted (^o).
+
Returns :
+Angle in radians (with decimal part).
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Angle DMS2Deg double   _Degrees,
double   _Minutes,
double   _Seconds
+
+ + + + + +
+   + + +

+Converts an angle from Degrees, Minutes, Seconds (^o,','') to a single quantity in degrees and fractions of a degree.

Parameters:
+ + + + +
_Degrees  +Number of degrees in angle (^o).
_Minutes  +Number of minutes in angle (').
_Seconds  +Number of seconds in angle ('').
+
Returns :
+Angle in degrees (with decimal part).
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Angle DMS2Rad double   _Degrees,
double   _Minutes,
double   _Seconds
+
+ + + + + +
+   + + +

+Converts an angle from Degrees, Minutes, Seconds (^o,','') to radians.

Parameters:
+ + + + +
_Degrees  +Number of degrees in angle (^o).
_Minutes  +Number of minutes in angle (').
_Seconds  +Number of seconds in angle ('').
+
Returns :
+Angle in radians (with decimal part).
+

+ + + + +
+ + + + + + + + + + +
Angle Rad2Deg Angle   _Radians
+
+ + + + + +
+   + + +

+Converts an angle from radians to degrees.

Parameters:
+ + +
_Radians  +Angle to be converted (rad).
+
Returns :
+returned number of degrees in angle (^o).
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Rad2DMS Angle   _Radians,
double &   Degrees,
double &   Minutes,
double &   Seconds
+
+ + + + + +
+   + + +

+Converts an angle from radians to degrees, minutes, second format.

Parameters:
+ + + + + +
_Radians  +Angle to be converted (rad).
Degrees  +returned number of degrees in angle (^o).
Minutes  +returned number of minutes in angle (').
Seconds  +returned number of seconds in angle ('').
+
+


Variable Documentation

+

+ + + + +
+ + +
const double PI = 3.14159 +
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/group__Zeit.html b/doc/html/group__Zeit.html new file mode 100644 index 0000000..d8a65d2 --- /dev/null +++ b/doc/html/group__Zeit.html @@ -0,0 +1,20 @@ + + +Time representation + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Time representation

+ + + +

Compounds

class  Zeit
+

Detailed Description

+Class encapsulating a representation of time and allowing for transformations between various forms of time.
Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 0000000..31bcf16 --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,39 @@ + + +Spacecraft Simulation Framework Documentation + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework Documentation

+

+

v0.1

Introduction +

+

+This is the introduction.

Rotation Toolbox +

Orbital Toolbox +

Attitude Toolbox +

Spacecraft Simulation Framework +

+

+

History +

+

+

Usage +

Step 1: Downloading +

Step 2: Compiling +

+

+

License +

This library is released under the GNU General Public License. +

+

Author +

Andrew Turner (ajturner@vt.edu) +

+


Generated on Thu Feb 27 13:46:15 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/main_8cpp.html b/doc/html/main_8cpp.html new file mode 100644 index 0000000..8f87678 --- /dev/null +++ b/doc/html/main_8cpp.html @@ -0,0 +1,54 @@ + + +main.cpp File Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

main.cpp File Reference

#include <Rotation.h>
+#include <stdio.h>
+#include <iostream.h>
+#include <RungeKutta.h>
+#include <Trigonometry.h>
+#include <TrigTest.h>
+ + + + +

Functions

int main ()
+

Function Documentation

+

+ + + + +
+ + + + + + + + + +
int main  
+
+ + + + + +
+   + + +

+

+


Generated on Thu Feb 27 13:46:18 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/modules.html b/doc/html/modules.html new file mode 100644 index 0000000..4dca10d --- /dev/null +++ b/doc/html/modules.html @@ -0,0 +1,36 @@ + + +Module Index + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework Modules

Here is a list of all modules: +
Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/namespaces.html b/doc/html/namespaces.html new file mode 100644 index 0000000..908af41 --- /dev/null +++ b/doc/html/namespaces.html @@ -0,0 +1,18 @@ + + +Namespace Index + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework Namespace List

Here is a list of all namespaces with brief descriptions: + + +
std
techsoft
+
Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/namespacestd.html b/doc/html/namespacestd.html new file mode 100644 index 0000000..b2bb12a --- /dev/null +++ b/doc/html/namespacestd.html @@ -0,0 +1,19 @@ + + +std Namespace Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

std Namespace Reference

+

+ + +
+


Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/namespacetechsoft.html b/doc/html/namespacetechsoft.html new file mode 100644 index 0000000..86f4e7c --- /dev/null +++ b/doc/html/namespacetechsoft.html @@ -0,0 +1,19 @@ + + +techsoft Namespace Reference + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

techsoft Namespace Reference

+

+ + +
+


Generated on Thu Feb 27 13:46:25 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/pages.html b/doc/html/pages.html new file mode 100644 index 0000000..1d8a0e5 --- /dev/null +++ b/doc/html/pages.html @@ -0,0 +1,20 @@ + + +Page Index + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Spacecraft Simulation Framework Related Pages

Here is a list of all related documentation pages: +
Generated on Thu Feb 27 13:46:26 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/doc/html/todo.html b/doc/html/todo.html new file mode 100644 index 0000000..7bc3a19 --- /dev/null +++ b/doc/html/todo.html @@ -0,0 +1,183 @@ + + +Todo List + + + +
+Main Page   Modules   Namespace List   Compound List   File List   Compound Members   File Members   Related Pages  
+

Todo List +

+
+
Class Attitude
Verify attitude is inheritable. +
+ +

+ +

+
Member DirectionCosineMatrix::GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle)
Implement DCM::GetEulerAngles function +
+ +

+ +

+
Member ModifiedRodriguezParameters::GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle) const
Implement ModifiedRodriguezParameters::GetEulerAngles Function +
+ +

+ +

+
Member ModifiedRodriguezParameters::Set(const double &_Angle1, const double &_Angle2, const double &_Angle3, const int &_Sequence)
Change implementation to calculate directly from Euler angles and not create a DCM? +
+ +

+ +

+
Member ModifiedRodriguezParameters::GetQuaternion() const
Implement to directly convert and not use a temporary quaternion +
+ +

+ +

+
Member Quaternion::GetEulerAxisAngle(Vector &_EulerAxis, double &_EulerAngle)
Implement Quaternion::GetEulerAngles function +
+ +

+ +

+
Member Quaternion::operator+(const Quaternion &_quat2) const
Add Normalize() to Vector Class +
+ +

+ +

+
Member Quaternion::Set(const Vector &_EulerAxis, const double &_EulerAngle)
Implement Quaternion::Set(EulerAngles, Sequence) as individual calcs instead of multiple conversions +
+ +

+ +

+
File Attitude.h
Make Attitude derivable for diff't types of attitude representations (point-to, etc) +

+Implement export & import plug-ins (STK, matlab, excel...) +

+ Add Attitude history storage +

+ +

+ +

+
File Environment.h
Fix to work w/ new rotation toolbox +
+ +

+ +

+
File Matrix.h
Add overloading of operators +

+ Reference cammva documentation +

+ +

+ +

+
Member crossP(const Vector &_v1, const Vector &_v2)
Implement crossP as part of Vector or CAMdoubleVector class +
+ +

+ +

+
Member eye(int _rowColumns)
Implement eye as part of Vector or CAMdoubleVector class +
+ +

+ +

+
Member norm2(const Vector &_inVector)
Implement norm2 as part of Vector or CAMdoubleVector class +
+ +

+ +

+
Member normalize(Vector &_inVector)
Implement normalize as part of Vector or CAMdoubleVector class +
+ +

+ +

+
Member normInf(const Vector &_inVector)
Implement normInf as part of Vector or CAMdoubleVector class +
+ +

+ +

+
Member skew(const Vector &_inVector)
Implement skew as part of Vector or CAMdoubleVector class +
+ +

+ +

+
Member trace(const Matrix &_inMatrix)
Implement trace as part of Vector or CAMdoubleVector class +
+ +

+ +

+
File Orbit.h
Implement encapsulation of orbit parameters +

+Add functionality for setting & retrieving w/ different representations +

+ Fix to work w/ new matrix toolbox +

+ +

+ +

+
File Plot.h
Implement functions for various methods of plotting +

+ Fix to work w/ new matrix toolbox +

+ +

+ +

+
File Rotation.cpp
Implement Gibbs vector representation +
+ +

+ +

+
File Rotation.h
Implement Gibbs vector representation +

+ Wrap Rotation library in a namespace +

+ +

+ +

+
File RungeKutta.h
Add test cases +
+ +

+ +

+
File Spacecraft.h
Fix to work w/ new rotation toolbox +
+ +

+ +

+
File SpacecraftToolboxConstants.h
Implement Gibbs vector representation +
+ +

+ +

+
File Trigonometry.h
Add an 'Angle Class'? +
+
Generated on Thu Feb 27 13:46:24 2003 for Spacecraft Simulation Framework by + +doxygen1.2.17
+ + diff --git a/packages/CVS/Entries b/packages/CVS/Entries new file mode 100644 index 0000000..a99c65d --- /dev/null +++ b/packages/CVS/Entries @@ -0,0 +1,3 @@ +/matrixLib.tar.gz/1.1/Thu Feb 27 19:55:50 2003// +/rotationLib.tar.gz/1.1/Thu Feb 27 19:48:57 2003// +D diff --git a/packages/CVS/Repository b/packages/CVS/Repository new file mode 100644 index 0000000..c3c9f28 --- /dev/null +++ b/packages/CVS/Repository @@ -0,0 +1 @@ +spacecraft/packages diff --git a/packages/CVS/Root b/packages/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/packages/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/packages/matrixLib.tar.gz b/packages/matrixLib.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..75c739dc1901668e848841dce64a8b6f745fee99 GIT binary patch literal 47221 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

QCA#? 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 bYM0k|tBJh-zrMQZFT#ea5EPJYNRa;n_lBF- literal 0 HcmV?d00001 diff --git a/packages/rotationLib.tar.gz b/packages/rotationLib.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..4b18e461037b7cb5e3a7bbf80248c61c74c30a75 GIT binary patch literal 51903 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 + return; +} + +odeFunctor Attitude::GetDynamicsEq() const +{ + return m_AttDynEqFuncPtr; +} + +void Attitude::SetDynamicsEq(odeFunctor _AttDynEqFuncPtr) +{ + m_AttDynEqFuncPtr = _AttDynEqFuncPtr; + m_Integrateable = true; + return; +} + +void Attitude::SetStateConversion(IntegratedAttitudeStateConversionFunction _ConversionFunction) +{ + m_AttitudeStateConversionFunction = _ConversionFunction; +} + +IntegratedAttitudeStateConversionFunction Attitude::GetStateConversion() const +{ + return m_AttitudeStateConversionFunction; +} + +void Attitude::SetControlTorques(const Vector &_ControlTorques) +{ + /** \todo add error checking */ + m_ControlTorques.initialize(_ControlTorques); + return; +} +Vector Attitude::GetControlTorques() const +{ + return m_ControlTorques; +} + +void Attitude::SetParameters(const Matrix &_Parameters) +{ + m_Parameters.initialize(_Parameters); +} + +Matrix Attitude::GetParameters() const +{ + return m_Parameters; +} + +Matrix Attitude::Propagate(const vector &_propTime) +{ + cout << "Begin propagating... " << endl; + m_pPropagator->Propagate(_propTime); + // Store the propagated states + return Matrix(3,3); +} + +bool Attitude::IsIntegrateable() +{ + return m_Integrateable; +} + +// ***************************** +// ******** ENVIRONMENT ******** +// ***************************** +void Attitude::SetEnvironment(Environment *_pEnvironment) +{ + m_pEnvironment = _pEnvironment; + m_EnvironmentForcesFunctor.Set(m_pEnvironment, &Environment::GetTorques); +} + +Environment* Attitude::GetEnvironment() const +{ + return m_pEnvironment; +} + +ObjectFunctor Attitude::GetEnvironmentForcesFunctor() +{ + return m_EnvironmentForcesFunctor; +} + +// ************************* +// ******** HISTORY ******** +// ************************* +AttitudeHistory& Attitude::GetHistoryObject() +{ + return m_AttitudeHistory; +} + +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Attitude.cpp,v $ +* Revision 1.11 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.10 2003/06/10 14:51:41 nilspace +* Changed GetHistory to GetHistoryObject +* +* Revision 1.9 2003/05/20 17:46:25 nilspace +* Updated comments. +* +* Revision 1.8 2003/04/28 20:12:44 nilspace +* GetHistory return by reference. +* +* Revision 1.7 2003/04/28 14:29:18 nilspace +* Added data member constructor calls in default constructor. +* +* Revision 1.6 2003/04/27 22:11:51 nilspace +* Moved all of the function definitions out of the class interface definition. +* +* Revision 1.5 2003/04/27 22:04:31 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/25 13:44:58 nilspace +* Updated to work with current History, Environment & Propagator objects. +* +* Revision 1.3 2003/04/23 21:54:32 nilspace +* Updated to work with AttitudeState, Environment. +* Removed the setting and getting of AngVel, AngAccel, Rotation. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:51:24 nilspace +* Initial submission in new directory. +* +******************************************************************************/ diff --git a/src/attitude/Attitude.h b/src/attitude/Attitude.h new file mode 100644 index 0000000..07435a5 --- /dev/null +++ b/src/attitude/Attitude.h @@ -0,0 +1,259 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Attitude.h +* \brief Interface to the Attitude class. +* \author $Author: rsharo $ +* \version $Revision: 1.11 $ +* \date $Date: 2003/10/18 21:37:27 $ +////////////////////////////////////////////////////////////////////////////////////////////////// +* \todo Make Attitude derivable for diff't types of attitude representations (point-to, etc) +* \todo Implement export & import plug-ins (STK, matlab, excel...) +* \todo Add Attitude history storage +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTITUDE_H__ +#define __ATTITUDE_H__ + +#include "Rotation.h" +#include "utils/Integrator.h" +#include "Propagator.h" +#include "AttitudeHistory.h" +#include "AttitudeState.h" +namespace O_SESSAME { +class Propagator; // forward declaration + +/*! \brief Defined function pointer to integrated attitude state conversion function. + * \ingroup PropagatorToolkit + * + * Converts a vector of meshpoints (from integrated states) to the corresponding generalized AttitudeState. + * @param _meshPoint vector of values of the meshpoint to be converted + * @param _convertedAttitudeState Calculated AttitudeState from the converted meshpoint that is returned to the caller. + */ +typedef void (*IntegratedAttitudeStateConversionFunction)(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState); + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup AttitudeToolkit Attitude Toolkit +* +*/ +/*! @defgroup AttitudeEquationsOfMotion Attitude Equations of Motion +* @ingroup AttitudeToolkit +* +*/ + +/*! \brief Class encapsulating the rotational attitude of a rigid body frame with respect to another frame. +* \ingroup AttitudeToolkit +* +* \detail The Attitude class allows for the attitude to be stored, retrieved, history logged, +* \todo Verify attitude is inheritable. +* \example testAttitudeIntegration.cpp +* \example testPropagation.cpp +*/ +class Attitude +{ +public: + /*! Default Constructor */ + Attitude(); + /*! Default Deconstructor */ + virtual ~Attitude(); + +public: + void SetStateObject(const AttitudeState &_newAttitudeState); + AttitudeState GetStateObject() const; + +private: + AttitudeState m_AttitudeState; + +// ***************************** +// ********** TORQUES ********** +// ***************************** +public: + /*! Set the control torques + * @param _ControlTorques 3-element vector of control torques applied about body primary axes [N-m] + */ + void SetControlTorques(const Vector &_ControlTorques); + + /*! Returns the current set of control torques + * @return 3-element vector of current control torques applied about body primary axes [N-m] + */ + Vector GetControlTorques() const; + + + /*! Return total sum of torques applied to the rigid body + * @return 3-element vector of current torques applied about body primary axes [N-m] + */ + Vector GetTorques() const; +private: + /*! 3-element vector of current control torques applied about body primary axes [N-m] */ + Vector m_ControlTorques; + +// ***************************** +// ******** PROPAGATION ******** +// ***************************** +public: + /*! Set the Dynamics Equation right-hand side file. + * Also makes the attitude integrateable. + * @param _AttDynEqFuncPtr pointer to the right-hand side dynamics equation + */ + void SetDynamicsEq(odeFunctor _AttDynEqFuncPtr); + + /*! Return the pointer to the Dynamics Equation right-hand side + * @return _AttDynEqFuncPtr pointer to the right-hand side dynamics equation + */ + odeFunctor GetDynamicsEq() const; + + + /*! \brief Set the Attitude state conversion function. + * @param _ConversionFunction pointer to the conversion function (takes a meshpoint and returns a Rotation object and Angular Velocity vector). + */ + void SetStateConversion(IntegratedAttitudeStateConversionFunction _ConversionFunction); + + /*! \brief Get the Attitude state conversion function. + * @return pointer to the conversion function (takes a meshpoint and returns a Rotation object and Angular Velocity vector). + */ + IntegratedAttitudeStateConversionFunction GetStateConversion() const; + + /*! Propagates the rigid body attitude forward in time. + * @param _time 3-element vector specifying the initial, final and stepsize of times to be integrated [timeInitial, timeStep, timeFinal] (s) + * @return matrix of integrated states. + */ + Matrix Propagate(const vector &_time); + + /*! + * \brief Sets the propagator used for integrating the attitude. + * @param _pPropagator Pointer to the propagator to be used. + */ + void SetPropagator(Propagator *_pPropagator); + + /*! \brief Returns whether the attitude is integrateable or not. + * Determined if there is a dynamics equation present. + * @return true if the attitude can be integrated, false if it can't. + */ + bool IsIntegrateable(); +private: + /*! pointer to the right-hand side dynamics equation */ + odeFunctor m_AttDynEqFuncPtr; + + /*! Conversion function for converting from the integrated states to a Rotation and Angular Velocity. */ + IntegratedAttitudeStateConversionFunction m_AttitudeStateConversionFunction; + + /*! Pointer to the propagator */ + Propagator *m_pPropagator; + + /*! \brief Is the attitude integrateable? (true if it is, false if is not) */ + bool m_Integrateable; + +// ***************************** +// ********* Physical ********** +// ***************************** +public: + void SetParameters(const Matrix &_Parameters); + Matrix GetParameters() const; + +private: + Matrix m_Parameters; + +// ***************************** +// ******** ENVIRONMENT ******** +// ***************************** +public: + /*! \brief Assign the environment to be used when evaluating attitude disturbance torques. + * The environment contains the list of torque disturbance functions, environment parameters, and + * central body definition of the spacecraft. This functions sets the pointer (reference) to the + * environment object. This environment should be the same as the orbit's environment if there is an + * orbit being modeled. + * @param _pNewEnvironment this variable is a pointer to the environment object to be stored. + */ + void SetEnvironment(Environment* _pNewEnvironment); + /*! \brief Return the reference to the environment object of the attitude. + * This function is useful for returning the current environment that is being used by the attitude. + * It can be used to inspect and set the environment variables (such as adding torque disturbance + * functions, setting the central body, or changing environment parameters), or to use the reference + * for setting another environment (the coupled orbit, or another spacecraft's orbit and attitude + * that are in the same environment as this spacecraft. + * @return this function returns a pointer to the environment object that is currently stored in the attitude. + */ + Environment* GetEnvironment() const; + + /*! \brief Returns the function reference (functor) to the function that evaluates the environment disturbance torques. + * This function is used to get the reference, or function pointer, to the environmental disturbance torque function. + * The reference may then be evalauated (\sa ObjectFunctor) to calculate the disturbance torques at a specified + * time, attitude, and possibly orbit, if applicable for the defined disturbance function (such as magnetic or gravity-gradient + * with a higher-order gravity model). + * @return this function returns a functor, or function reference of an object's member function, that refers to the disturbance function. + */ + ObjectFunctor GetEnvironmentForcesFunctor(); +private: + /*! \brief Pointer to the Environment object */ + Environment *m_pEnvironment; + /*! \brief Pointer to the Environment forces function */ + ObjectFunctor m_EnvironmentForcesFunctor; +// ************************* +// ******** HISTORY ******** +// ************************* +public: + /*! \brief Retrieve a reference to the attitude's state history. + * By returning a reference, no copy is made, which is more efficient than copying a large matrix of + * states. The user can then inspect the history (\sa History, \sa AttitudeHistory). + * @return this function returns a reference, which acts as an object, but is also like a pointer. + */ + AttitudeHistory& GetHistoryObject(); + +private: + /*! \brief This private data member is the stored attitude state, including [time, rotation, angular velocity] */ + AttitudeHistory m_AttitudeHistory; + + +}; +} // close namespace O_SESSAME +#endif +/*!*************************************************************************** +* $Log: Attitude.h,v $ +* Revision 1.11 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.10 2003/06/10 14:51:42 nilspace +* Changed GetHistory to GetHistoryObject +* +* Revision 1.9 2003/05/20 17:46:25 nilspace +* Updated comments. +* +* Revision 1.8 2003/05/13 18:50:47 nilspace +* Fixed comments. +* +* Revision 1.7 2003/04/28 20:12:45 nilspace +* GetHistory return by reference. +* +* Revision 1.6 2003/04/27 22:11:51 nilspace +* Moved all of the function definitions out of the class interface definition. +* +* Revision 1.5 2003/04/27 22:04:31 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/25 13:44:58 nilspace +* Updated to work with current History, Environment & Propagator objects. +* +* Revision 1.3 2003/04/23 21:54:33 nilspace +* Updated to work with AttitudeState, Environment. +* Removed the setting and getting of AngVel, AngAccel, Rotation. +* +* Revision 1.4 2003/03/27 20:25:17 nilspace +* Implemented calling the propagator & history objects. +* +* Revision 1.3 2003/03/27 02:48:54 nilspace +* Added the Propagator object functionality. Documented some of the new functions.Fixed history storage. +* +* Revision 1.2 2003/03/25 19:43:37 nilspace +* fixed to pre-ruined state. +* Changed enum to be auto number defining. +* +* Revision 1.1 2003/03/25 02:41:05 nilspace +* initial Submission. Attitude.h may not be current due to lost copy from ProjectBuilder crash. +* +* Revision 1.1 2003/02/27 18:37:26 nilspace +* Initial submission of Attitude class implementation. +* +* +******************************************************************************/ diff --git a/src/attitude/AttitudeModels/CVS/Entries b/src/attitude/AttitudeModels/CVS/Entries new file mode 100644 index 0000000..6ff9125 --- /dev/null +++ b/src/attitude/AttitudeModels/CVS/Entries @@ -0,0 +1,2 @@ +/QuaternionAngVelDynamics.h/1.3/Sat Oct 18 21:37:27 2003// +D diff --git a/src/attitude/AttitudeModels/CVS/Repository b/src/attitude/AttitudeModels/CVS/Repository new file mode 100644 index 0000000..493c651 --- /dev/null +++ b/src/attitude/AttitudeModels/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/attitude/AttitudeModels diff --git a/src/attitude/AttitudeModels/CVS/Root b/src/attitude/AttitudeModels/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/attitude/AttitudeModels/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/attitude/AttitudeModels/QuaternionAngVelDynamics.h b/src/attitude/AttitudeModels/QuaternionAngVelDynamics.h new file mode 100644 index 0000000..42ab58f --- /dev/null +++ b/src/attitude/AttitudeModels/QuaternionAngVelDynamics.h @@ -0,0 +1,136 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file AttituteDynamics_QuaternionAngVel.h +* \brief Attitude Dynamic equations using Quaternions and Angular Velocities. +* \author $Author: rsharo $ +* \version $Revision: 1.3 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_ATTDYN_QUATANGVEL_H__ +#define __OSESSAME_ATTDYN_QUATANGVEL_H__ +#include "matrix/Matrix.h" +#include "Integrator.h" +#include "utils/Time.h" +#include "Orbit.h" +#include "OrbitState.h" +#include "Attitude.h" +#include +using namespace std; +using namespace O_SESSAME; + +/*! \brief Attitude state conversion function from Quaternion and Angular Velocity state vector. +* \relates AttituteDynamics_QuaternionAngVel +* +* This function converts a matrix of states from the AttituteDynamics_QuaternionAngVel right-hand +* side function into an AttitudeState object. This conversion function is necessary for propagators +* to store to an AttitudeHistory object regardless of the equations of motion state vector being +* used. +* @param _meshPoint State vector from integration mesh point, [Quaternion (4), AngularVelocity (3)]. +* @param _convertedAttitudeState AttitudeState object that is converted from the mesh point vector. +*/ +static void QuaternionAngVelConvFunc(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState) +{ + static Vector tempQ(4); + static Vector tempAngVel(3); + + tempQ(_) = ~_meshPoint(_,_(2, 5)); + tempAngVel(_) = ~_meshPoint(1, _(6, 8)); + _convertedAttitudeState.SetState(Rotation(Quaternion(tempQ)), tempAngVel); + return; +} + +/*! \brief Attitude Dynamics equation using Quaternions and Angular Velocities as the state variables +* @ingroup AttitudeEquationsOfMotion +* +* +The rotation of a rigid body is described by the kinematic equations of motion and the kinetic equations +of motion. As discussed above, the kinematics specifically model the current attitude of the body with +respect to time. The dynamics are characterized by the absolute angular velocity vector, $\omega$. + +Each attitude representation has a set of equations that describe its time rate of change due to the +dynamics of the rigid body. + +The propagation of the Quaternion kinematics is defined as: +\f[ +\dot {\bar{\bf q}} = {Q}\left(\bar{\bf q}\right){\bf \omega} +\f] +\f[ + = \frac{1}{2}\begin{bmatrix} + {{\bf{q}}^{\times} + q_4 {\bf 1}} \\ + { - {\bf{q}}^T } \\ +\end{bmatrix} {\bf \omega} +\f] +\par +The differential equations for the angular velocity in the body frame are based on Euler's equation: +\f[ +\bf{I}\dot{\bf \omega} = \bf{g} - \omega \times \bf{I}\omega +\f] +where \f$\textbf{I}\f$ is the spacecraft moment of inertia matrix, \f$\omega\f$ is the body angular +velocity, and \f$\textbf{g}\f$ are the spacecraft torques. + +This equation can be verified for an axis-symmetric body under torques about the 1,2 axes as follows: +\f[ +\omega_{1} = \omega_{01}\cos{\omega_{p}t} + \omega_{02}\sin{\omega_{p}t} + \frac{1}{I_{T}}\int^{t}_{0}{[g_{1}(\tau)\cos{(\omega_{p}(t-\tau))}+g_{2}(\tau)\sin{(\omega_{p}(t-\tau))}]d\tau} +\f] +\f[ +\omega_{2} = -\omega_{01}\sin{\omega_{p}t} + \omega_{02}\cos{\omega_{p}t} + \frac{1}{I_{T}}\int^{t}_{0}{[-g_{1}(\tau)\sin{(\omega_{p}(t-\tau))}+g_{2}(\tau)\cos{(\omega_{p}(t-\tau))}]d\tau} +\f] +\f[ +\omega_{3} = \omega_{03} +\f] + +* @param _time current time (in seconds) +* @param _state vector of states, \f$\left[\bar{\bf q},\bf{\omega}\right]^{T}\f$ (-, radians/second) +* @param _pOrbit pointer to the current Orbit instance +* @param _pAttitude pointer to the current Attitude instance +* @param _parameters additional parameters for integration \f$\left[MOI(3\times3); MOI^{-1}(3\times3)\right]\f$ +* @param _torqueFuncPtr pointer to the torque calculating function +* @return This attitude dynamics RHS returns the 7-element vector of time derivatives of state \f$\left[\dot{\bar{\mathbf q}},\dot{\mathbf \omega}\right]^{T}\f$ +*/ +static Vector AttituteDynamics_QuaternionAngVel(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_torqueFuncPtr) +{ + static Vector stateDot(7); + static Matrix bMOI(3,3); + static Matrix invMOI(3,3); + static Matrix qtemp(4,3); + static Vector Tmoment(3); + static Vector qIn(4); + static Vector wIn(3); + qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3)); + wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6)); + qIn /= norm2(qIn); + +// _attitudeState->SetState(Rotation(Quaternion(qIn)), wIn); // Need to speed up in some way + qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3); + qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2))); + + bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2)); + invMOI = _parameters(_(MatrixIndexBase+3,MatrixIndexBase+5),_(MatrixIndexBase+0,MatrixIndexBase+2)); + Tmoment = _torqueFuncPtr.Call(_time, _Orbit->GetStateObject(), _Attitude->GetStateObject()); + + stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = 0.5 * qtemp * wIn; + stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = (invMOI * (Tmoment - skew(wIn) * (bMOI * wIn))); + return stateDot; +} + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: QuaternionAngVelDynamics.h,v $ +* Revision 1.3 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.2 2003/06/12 20:51:14 nilspace +* Requires a precomputer MOI inverse. +* +* Revision 1.1 2003/06/12 19:17:42 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/attitude/AttitudeState.cpp b/src/attitude/AttitudeState.cpp new file mode 100644 index 0000000..88a7dae --- /dev/null +++ b/src/attitude/AttitudeState.cpp @@ -0,0 +1,122 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file AttitudeState.cpp +* \brief Implementation of the Attitude State Interface Class. +* \author $Author: nilspace $ +* \version $Revision: 1.5 $ +* \date $Date: 2003/06/12 23:07:08 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "AttitudeState.h" +#include "orbitstaterep/Keplerian.h" +#include "OrbitState.h" +namespace O_SESSAME { +AttitudeState::AttitudeState() : m_AngularVelocity(3) +{ + +} +AttitudeState::~AttitudeState() +{ + /*! \todo delete AttitudeState data members */ +/* + if(m_pAttitudeFrame) + delete m_pAttitudeFrame;*/ +} +AttitudeState::AttitudeState(const Rotation &_Rot, AttitudeFrame* _pAttFrame) +{ + SetRotation(_Rot); + SetAttitudeFrame(_pAttFrame); +} + +AttitudeState::AttitudeState(const Rotation &_Rot, const Vector &_AngVel, AttitudeFrame* _pAttFrame) +{ + SetRotation(_Rot); + SetAngularVelocity(_AngVel); + SetAttitudeFrame(_pAttFrame); +} +void AttitudeState::SetAttitudeFrame(AttitudeFrame* _pNewAttitudeFrame) +{ /** \todo add conversion of Rotation to the new frame */ + m_pAttitudeFrame = _pNewAttitudeFrame; + return; +} + +AttitudeFrame* AttitudeState::GetAttitudeFrame() const +{ + return m_pAttitudeFrame; +} + +void AttitudeState::SetRotation(const Rotation &_Rot) +{ + m_AttitudeRotation = _Rot; +} + +void AttitudeState::SetRotation(const Rotation &_Rot, AttitudeFrame* _pAttFrame) +{ + SetRotation(_Rot); + SetAttitudeFrame(_pAttFrame); +} + +Rotation AttitudeState::GetRotation() const +{ + return m_AttitudeRotation; +} + +void AttitudeState::SetState(const Rotation& _Rotation, const Vector& _AngVel, AttitudeFrame* _attFrame) +{ + SetRotation(_Rotation); + SetAngularVelocity(_AngVel); + if(_attFrame) + SetAttitudeFrame(_attFrame); + return; +} + + +Vector AttitudeState::GetState(const RotationType& _rotType, AttitudeFrame* _attFrame, const int& _Sequence) const +{ + Vector rotOutput = GetRotation().GetRotation(_rotType, _Sequence); + Vector output(rotOutput.getIndexBound() + m_AngularVelocity.getIndexBound()); + output(_(VectorIndexBase, VectorIndexBase + rotOutput.getIndexBound() - 1)) = rotOutput(_); + output(_(VectorIndexBase + rotOutput.getIndexBound(), VectorIndexBase + rotOutput.getIndexBound() + m_AngularVelocity.getIndexBound() - 1)) = m_AngularVelocity(_); + return output; +} + +void AttitudeState::SetAngularVelocity(const Vector &_angVel) +{ + m_AngularVelocity = _angVel; +} + +Vector AttitudeState::GetAngularVelocity() const +{ + return m_AngularVelocity; +} + +Rotation AttitudeState::GetRotation2Orbital(const OrbitState& _orbState) const +{ + Keplerian kepElements; kepElements.SetPositionVelocity(_orbState.GetStateRepresentation()->GetPositionVelocity()); + return GetRotation() * R3(kepElements.GetLongAscNode()) * R1(kepElements.GetInclination()) * R3(kepElements.GetArgPerigee()); +} + +} // close namespace O_SESSAME +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: AttitudeState.cpp,v $ +* Revision 1.5 2003/06/12 23:07:08 nilspace +* Fixed to calculate Orbital rotation. +* +* Revision 1.4 2003/04/27 22:04:31 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.3 2003/04/23 19:16:35 nilspace +* Removed default argument for AttitudeState::SetState. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:51:24 nilspace +* Initial submission in new directory. +* +* +******************************************************************************/ diff --git a/src/attitude/AttitudeState.h b/src/attitude/AttitudeState.h new file mode 100644 index 0000000..0fbe96a --- /dev/null +++ b/src/attitude/AttitudeState.h @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file AttitudeState.h +* \brief Interface to the AttitudeState class. +* \author $Author: rsharo $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ATTITUDE_STATE_H__ +#define __SSF_ATTITUDE_STATE_H__ + +#include "Matrix.h" +#include "Rotation.h" + +namespace O_SESSAME { +typedef int AttitudeFrame; /** \todo Implement AttitudeFrame class */ +class OrbitState; + +/*! \brief Encapsulation of an Attitude State, including its coordinate type and reference frame. +* \ingroup AttitudeToolkit +* +* \detail AttitudeState encapsulates an instantaneous representation of an attitude, as well as +* the frame from which it is referenced. Also included is all the functionality for converting +* between the frames and accessing or changing the associated rotation. +* +* \par Examples: +\code +AttitudeState satAtt; +Vector AngVel(3); AngVel(1) = 0.1; +satAtt.SetRotation(Rotation(Quaternion(0,0,0,1))); +satAtt.SetFrame(new AttitudeFrameBO); +satAtt.GetFrame()->SetReference(satOrbitState); +satAtt.SetAngularVelocity(AngVel); + +cout << satAtt.GetRotation().GetDCM() << endl; +\endcode + +* \example testAttitudeIntegration.cpp +* \example testPropagation.cpp +*/ +class AttitudeState +{ +public: + /*! \brief Default Constructor. + */ + AttitudeState(); + /*! \brief Default Deconstructor. + */ + virtual ~AttitudeState(); + + /*! \brief Creates an attitude state given a rotation and attitude frame (defaults to no frame) + * @param _Rot rotation to be stored + * @param _pAttFrame pointer to the attitude reference frame + */ + AttitudeState(const Rotation &_Rot, AttitudeFrame* _pAttFrame = NULL); + + /*! \brief Creates an attitude state given a rotation, an angular velocity and attitude frame (defaults to no frame) + * @param _Rot rotation to be stored + * @param _AngVel angular velocity (rad/s) + * @param _pAttFrame pointer to the attitude reference frame + */ + AttitudeState(const Rotation &_Rot, const Vector &_AngVel, AttitudeFrame* _pAttFrame = NULL); + + /*! \brief Set the reference frame of the stored attitude. + * \detail Will convert the old rotation to the new attitude frame if one was specified. + * @param _pNewAttitudeFrame pointer to the new reference frame + */ + void SetAttitudeFrame(AttitudeFrame* _pNewAttitudeFrame); + + /*! \brief Returns a pointer to the attitude reference frame. + * @return pointer to the attitude reference frame + */ + AttitudeFrame* GetAttitudeFrame() const; + + /*! \brief Set the attitude state given a rotation, an angular velocity and attitude frame (defaults to no frame) + * @param _Rot rotation to be stored + * @param _AngVel angular velocity (rad/s) + * @param _pAttFrame pointer to the attitude reference frame + */ + void SetState(const Rotation& _Rotation, const Vector& _AngVel, AttitudeFrame* _attFrame = NULL); + + /*! \brief Return the attitude state rotation in vector format. + * @param _rotType Rotation type to return the attitude state in (ie QUAT_TYPE, MRP_TYPE, etc.) + * @param _attFrame corresponding reference frame to return the rotation in (if none is specified, returns the rotation in the stored reference frame) + * @param _Sequence if the requested rotation type is EULER_ANGLE_TYPE, then specify the desired rotation sequence. + * @return full n x 1 vector of state values corresponding to the rotation and angular velocity components (n is the number of elements in specified rotation return type) + */ + Vector GetState(const RotationType& _rotType = Quaternion_Type, AttitudeFrame* _attFrame = NULL, const int& _Sequence = 123) const; + + /*! \brief Set the stored rotation. + * @param _Rot rotation to be stored as the state. + */ + void SetRotation(const Rotation &_Rot); + + /*! \brief Set the stored rotation and corresponding reference frame. + * @param _Rot rotation to be stored as the state. + * @param _pAttFrame reference frame of the specified attitude. + */ + void SetRotation(const Rotation &_Rot, AttitudeFrame* _pAttFrame); + + /*! \brief Returns the current rotation of the attitude state. + * @param Rotation of the attitude state. + */ + Rotation GetRotation() const; + + /*! \brief Set the stored angular velocity state. + * @param _angVel 3x1 Vector of angular velocities about reference frame (rad/s) + */ + void SetAngularVelocity(const Vector &_angVel); + + /*! \brief Returns the stored angular velocity state. + * @return 3x1 Vector of angular velocities about reference frame (rad/s) + */ + Vector GetAngularVelocity() const; + + /*! \brief Calculates the rotation from the current attitude state to the specified orbit reference frame. + * + * \todo Implement algorithm. + * @param _orbState orbit state to use for specifying the reference orbital frame. + * @return Rotation from current attitude frame to orbital frame. + */ + Rotation GetRotation2Orbital(const OrbitState& _orbState) const; + +private: + Rotation m_AttitudeRotation; /*!< internally stored attitude state rotation */ + Vector m_AngularVelocity; /*!< internally stored angular velocity */ + AttitudeFrame* m_pAttitudeFrame; /*!< rotation reference frame */ +}; + +} // close namespace O_SESSAME +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: AttitudeState.h,v $ +* Revision 1.8 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.7 2003/06/12 23:07:08 nilspace +* Fixed to calculate Orbital rotation. +* +* Revision 1.6 2003/06/12 17:59:35 nilspace +* Added GetRotation2Orbit function. +* +* Revision 1.5 2003/05/20 17:46:25 nilspace +* Updated comments. +* +* Revision 1.4 2003/05/13 18:50:24 nilspace +* Fixed comments. +* +* Revision 1.3 2003/04/27 22:04:31 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:51:24 nilspace +* Initial submission in new directory. +* +******************************************************************************/ diff --git a/src/attitude/CVS/Entries b/src/attitude/CVS/Entries new file mode 100644 index 0000000..54841ec --- /dev/null +++ b/src/attitude/CVS/Entries @@ -0,0 +1,8 @@ +/Attitude.cpp/1.11/Sat Oct 18 21:37:27 2003// +/Attitude.h/1.11/Sat Oct 18 21:37:27 2003// +/AttitudeState.cpp/1.5/Thu Jun 12 23:07:08 2003// +/AttitudeState.h/1.8/Sat Oct 18 21:37:27 2003// +/Jamfile/1.5/Mon Dec 8 14:48:27 2003// +/Makefile/1.5/Sat Oct 18 21:37:27 2003// +/attitude.pro/1.3/Sat Oct 18 21:37:27 2003// +D/AttitudeModels//// diff --git a/src/attitude/CVS/Repository b/src/attitude/CVS/Repository new file mode 100644 index 0000000..ec13e07 --- /dev/null +++ b/src/attitude/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/attitude diff --git a/src/attitude/CVS/Root b/src/attitude/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/attitude/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/attitude/Jamfile b/src/attitude/Jamfile new file mode 100644 index 0000000..fe9ae7c --- /dev/null +++ b/src/attitude/Jamfile @@ -0,0 +1,29 @@ +########################################### +# Jamfile for the Attitude level directory +# +# $Author: simpliciter $ +# $Revision: 1.5 $ +# $Date: 2003/12/08 14:48:27 $ +########################################### + +SubDir OPENSESSAME_ROOT src attitude ; + +Objects Attitude.cpp AttitudeState.cpp ; +ObjectHdrs Attitude.cpp AttitudeState.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)attitude : Attitude$(SUFOBJ) AttitudeState$(SUFOBJ) ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)attitude$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : Attitude.h AttitudeState.h ; + + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.5 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# *****************************************************************************/ + + diff --git a/src/attitude/Makefile b/src/attitude/Makefile new file mode 100644 index 0000000..9218fd6 --- /dev/null +++ b/src/attitude/Makefile @@ -0,0 +1,184 @@ +############################################################################# +# Makefile for building: ../../lib/libosessame_attitude.a +# Generated by qmake (1.02a) on: Sat Oct 18 17:32:57 2003 +# Project: attitude.pro +# Template: lib +# Command: $(QMAKE) attitude.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +LEX = flex +YACC = yacc +CFLAGS = -pipe -Wall -W -g +CXXFLAGS = -pipe -Wall -W -g +LEXFLAGS = +YACCFLAGS= -d +INCPATH = -I../matrix -I../rotation -I../attitude -I../orbit -I../datahandling -I../dynamics -I../environment -I.. -I$(QTDIR)/mkspecs/default +AR = ar cqs +RANLIB = +MOC = $(QTDIR)/bin/moc +UIC = $(QTDIR)/bin/uic +QMAKE = qmake +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE= $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = +DEL_DIR = +MOVE = mv + +####### Output directory + +OBJECTS_DIR = ../../objects/ + +####### Files + +HEADERS = Attitude.h \ + AttitudeState.h +SOURCES = Attitude.cpp \ + AttitudeState.cpp +OBJECTS = ../../objects/Attitude.o \ + ../../objects/AttitudeState.o +FORMS = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = +DIST = +QMAKE_TARGET = osessame_attitude +DESTDIR = ../../lib/ +TARGET = ../../lib/libosessame_attitude.a + +first: all +####### Implicit rules + +.SUFFIXES: .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: Makefile $(TARGET) + +staticlib: $(TARGET) + +$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) + test -d ../../lib/ || mkdir -p ../../lib/ + -rm -f $(TARGET) + $(AR) $(TARGET) $(OBJECTS) $(OBJMOC) + + +mocables: $(SRCMOC) + +$(MOC): + ( cd $(QTDIR)/src/moc ; $(MAKE) ) + +Makefile: attitude.pro $(QTDIR)/mkspecs/default/qmake.conf + $(QMAKE) attitude.pro +qmake: + @$(QMAKE) attitude.pro + +dist: + @mkdir -p ../../objects/osessame_attitude && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) ../../objects/osessame_attitude/ && ( cd `dirname ../../objects/osessame_attitude` && $(TAR) osessame_attitude.tar osessame_attitude && $(GZIP) osessame_attitude.tar ) && mv `dirname ../../objects/osessame_attitude`/osessame_attitude.tar.gz . && rm -rf ../../objects/osessame_attitude + +uiclean: + +clean: + -rm -f $(OBJECTS) + -rm -f *~ core *.core + + +####### Sub-libraries + +distclean: clean + -rm -f ../../lib/$(TARGET) $(TARGET) + + +FORCE: + +####### Compile + +../../objects/Attitude.o: Attitude.cpp Attitude.h \ + ../rotation/Rotation.h \ + ../dynamics/Propagator.h \ + ../datahandling/AttitudeHistory.h \ + AttitudeState.h \ + ../orbit/Orbit.h \ + ../attitude/Attitude.h \ + ../datahandling/OrbitHistory.h \ + ../environment/Environment.h \ + ../orbit/OrbitState.h \ + ../matrix/Matrix.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h \ + ../datahandling/History.h \ + ../orbit/orbitstaterep/PositionVelocity.h \ + ../attitude/AttitudeState.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/Attitude.o Attitude.cpp + +../../objects/AttitudeState.o: AttitudeState.cpp AttitudeState.h \ + ../orbit/orbitstaterep/Keplerian.h \ + ../orbit/OrbitState.h \ + ../matrix/Matrix.h \ + ../rotation/Rotation.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h \ + ../orbit/orbitframes/OrbitFrame.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/AttitudeState.o AttitudeState.cpp + +####### Install + +install: all + +uninstall: + diff --git a/src/attitude/attitude.pro b/src/attitude/attitude.pro new file mode 100644 index 0000000..31aebe0 --- /dev/null +++ b/src/attitude/attitude.pro @@ -0,0 +1,25 @@ +# +# $Id: attitude.pro,v 1.3 2003/10/18 21:37:27 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = Attitude.h AttitudeState.h +SOURCES = Attitude.cpp AttitudeState.cpp +TARGET = osessame_attitude +VERSION = 1.0 +DESTDIR = ../../lib/ +INCLUDEPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment .. +CONFIG = console staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment ../utils diff --git a/src/datahandling/AttitudeHistory.cpp b/src/datahandling/AttitudeHistory.cpp new file mode 100644 index 0000000..b35c8da --- /dev/null +++ b/src/datahandling/AttitudeHistory.cpp @@ -0,0 +1,214 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file History.cpp +* \brief Encapsulation of History memento object. +* \author $Author: nilspace $ +* \version $Revision: 1.10 $ +* \date $Date: 2003/05/27 17:35:52 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "AttitudeHistory.h" +namespace O_SESSAME { + +AttitudeHistory::AttitudeHistory() +{ + ResetHistory(); + m_AttitudeHistory.reserve(HISTORY_RESERVE_SIZE); + m_AttitudeInterpolations.reserve(HISTORY_RESERVE_SIZE); +} + +AttitudeHistory::~AttitudeHistory() +{ + +} + +void AttitudeHistory::AppendHistory(const double &_appendTime, const Rotation &_appendRotation, const Vector &_appendAngVel) +{ + AppendHistory(ssfTime(_appendTime), AttitudeState(_appendRotation, _appendAngVel)); +} + +void AttitudeHistory::AppendHistory(const ssfTime &_appendTime, const Rotation &_appendRotation, const Vector &_appendAngVel) +{ + History::AppendHistory(_appendTime); + m_AttitudeHistory.push_back(AttitudeState(_appendRotation, _appendAngVel)); + return; +} + +void AttitudeHistory::AppendHistory(const double &_appendTime, const AttitudeState &_appendAttitudeState) +{ + AppendHistory(ssfTime(_appendTime), _appendAttitudeState); +} + +void AttitudeHistory::AppendHistory(const ssfTime &_appendTime, const AttitudeState &_appendAttitudeState) +{ + History::AppendHistory(_appendTime); + m_AttitudeHistory.push_back(_appendAttitudeState); + return; +} + +/*! \todo figure out how to append a large chunk of one vector<> to another */ +void AttitudeHistory::AppendHistory(const vector &_appendTime, const vector &_appendAttitudeState) +{ + vector::const_iterator iter = _appendAttitudeState.begin(); + // History::AppendHistory returns the distance from the end over any overlapping states. + vector::difference_type retDistance = History::AppendHistory(_appendTime); + + // If there is an overlap, delete the attitude states following the overlap point. + if(retDistance != 0) + m_AttitudeHistory.erase(m_AttitudeHistory.end()-retDistance, m_AttitudeHistory.end()); + + for(iter = _appendAttitudeState.begin(); iter != _appendAttitudeState.end(); ++iter) + m_AttitudeHistory.push_back(*iter); + + return; +} + +/*! \todo Determine if the multiple AppendHistory's can be combined in some smart way. */ +void AttitudeHistory::AppendHistory(const vector &_appendTime, const vector &_appendRotation, const vector &_appendAngVel) +{ + vector::const_iterator iterTime; + vector::const_iterator iterRot; + iterRot = _appendRotation.begin(); + vector::const_iterator iterVec; + iterVec = _appendAngVel.begin(); + + for(iterTime = _appendTime.begin(); iterTime != _appendTime.end(); ++iterTime) + { + AppendHistory(*iterTime, *iterRot, *iterVec); + ++iterRot; + ++iterVec; + } + return; +} + +void AttitudeHistory::ResetHistory() +{ + vector newAttitude(0); + m_AttitudeHistory.swap(newAttitude); + History::ResetHistory(); + return; +} + + +Matrix AttitudeHistory::GetHistory(const RotationType &_rotType) +{ + // initialize the output matrix based on the size of the desired output rotation, the angular velocity + // output, and an element for time. The number of rows is equal to the number of time elements. + int RotVectorSize = (m_AttitudeHistory.back()).GetRotation().GetRotation(_rotType).getIndexBound(); + int AngVelVectorSize = (m_AttitudeHistory.back()).GetAngularVelocity().getIndexBound(); + Matrix returnMatrix(m_TimeHistory.size(), 1 + RotVectorSize + AngVelVectorSize); + + for(int ii = 0; ii < m_TimeHistory.size(); ii++) + { + returnMatrix(MatrixIndexBase + ii, MatrixIndexBase) = m_TimeHistory[ii].GetSeconds(); + returnMatrix(MatrixIndexBase + ii, _(MatrixIndexBase+1,MatrixIndexBase + RotVectorSize)) = ~m_AttitudeHistory[ii].GetRotation().GetRotation(_rotType); + returnMatrix(MatrixIndexBase + ii, _(MatrixIndexBase + 1 + RotVectorSize, MatrixIndexBase + RotVectorSize + AngVelVectorSize)) = ~(m_AttitudeHistory[ii].GetAngularVelocity()(_)); + } + return returnMatrix; +} + +AttitudeState AttitudeHistory::GetState(const ssfTime& _requestedTime) +{ + Rotation tempRot; + Vector tempAngVel(3); + GetState(_requestedTime, tempRot, tempAngVel); + return AttitudeState(tempRot, tempAngVel); +} +void AttitudeHistory::GetState(const ssfTime& _requestedTime, Rotation& _returnRotation, Vector& _returnAngVelVector) +{ + int RotVectorSize = QUATERNION_SIZE; + int AngVelVectorSize = (m_AttitudeHistory.back()).GetAngularVelocity().getIndexBound(); + + // History::GetState returns the index of the nearest state. + vector::difference_type nearestTimeIndex = History::GetState(_requestedTime); + + int numDataPoints = 0; + if(m_OriginalInterpolator) + numDataPoints = m_OriginalInterpolator->GetNumberDataPoints(); + else /*! \todo implement better error handling strategy */ + return; + Vector timeVector(numDataPoints); + Matrix dataMatrix(numDataPoints, RotVectorSize+AngVelVectorSize); + Vector tempVector(RotVectorSize+AngVelVectorSize); + + // See if there is data at the requested time. + if(m_TimeHistory[nearestTimeIndex] != _requestedTime) + { + // Determine if there is currently an interpolation through the requested point. + // if there isn't, create one, then evaluate the interpolation at the requested data point. + while(m_AttitudeInterpolations.capacity() < nearestTimeIndex) + { + m_AttitudeInterpolations.reserve(m_AttitudeHistory.capacity() + HISTORY_RESERVE_SIZE); + } + // Check to see if the data is initialized to hold an interpolation + if(!m_AttitudeInterpolations[nearestTimeIndex]) + { + // fill in the 'missing' interpolations + for(int kk = m_AttitudeInterpolations.size(); kk < nearestTimeIndex; ++kk) + m_AttitudeInterpolations.push_back(m_OriginalInterpolator->NewPointer()); + + m_AttitudeInterpolations.push_back(m_OriginalInterpolator->NewPointer()); + } + // Calculate the interpolation parameters if necessary + if(!m_AttitudeInterpolations[nearestTimeIndex]->GetValid()) + { + for(int ii = 1; ii <= numDataPoints; ++ii) + { + timeVector(ii) = m_TimeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetSeconds(); + dataMatrix(ii,_(1,RotVectorSize)) = ~m_AttitudeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetRotation().GetRotation(Quaternion_Type); + dataMatrix(ii,_(RotVectorSize+1,RotVectorSize+AngVelVectorSize)) = ~m_AttitudeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetAngularVelocity(); + } + + m_AttitudeInterpolations[nearestTimeIndex]->Interpolate(timeVector, dataMatrix); + } + + tempVector = m_AttitudeInterpolations[nearestTimeIndex]->Evaluate(_requestedTime.GetSeconds()); + _returnRotation.Set(Quaternion(~tempVector(_(1,4)))); + _returnAngVelVector(_) = tempVector(_(5,7)); + } + else + { // there happens to be meshpoint data at the requested time, return it. + _returnRotation = m_AttitudeHistory[nearestTimeIndex].GetRotation(); + _returnAngVelVector = m_AttitudeHistory[nearestTimeIndex].GetAngularVelocity(); + } + + return; +} + +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: AttitudeHistory.cpp,v $ +* Revision 1.10 2003/05/27 17:35:52 nilspace +* Updated to prevent errors. +* +* Revision 1.9 2003/05/20 17:50:01 nilspace +* Updated comments. +* +* Revision 1.8 2003/05/13 18:45:35 nilspace +* Added interpolation functionality. +* +* Revision 1.7 2003/05/01 18:24:36 nilspace +* Prevented overlapping Appends by removing the old states and times. +* +* Revision 1.6 2003/04/29 20:57:46 nilspace +* Updated to work with Propagator. +* +* Revision 1.5 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/25 17:14:59 nilspace +* Added OrbitHistory & made sure it builds. +* Moved Appending time to History.cpp. +* +* Revision 1.3 2003/04/23 17:00:46 nilspace +* Changed to work with AttitudeState and not Rotation and AngVel seperately. +* Time is now stored as ssfTime. +* +* Revision 1.1 2003/03/27 20:29:19 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/datahandling/AttitudeHistory.h b/src/datahandling/AttitudeHistory.h new file mode 100644 index 0000000..0d64356 --- /dev/null +++ b/src/datahandling/AttitudeHistory.h @@ -0,0 +1,214 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file AttitudeHistory.h +* \brief Interface to the Attitude History class. +* \author $Author: rsharo $ +* \version $Revision: 1.11 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __ATTITUDE_HISTORY_H__ +#define __ATTITUDE_HISTORY_H__ + +#include "Rotation.h" +#include "AttitudeState.h" +#include "utils/Time.h" +#include "History.h" +#include +using namespace std; +namespace O_SESSAME { + +/*! \brief Class for storing a time history of attitude states. +* \ingroup StateHistory +* +* The AttitudeHistory class provides a container of previous AttitudeState objects. The user +* may append new states, reset the collection of states, or return the attitude history +* in a matrix. If the user appends attitude states at time which earlier than the end +* of the current history, the current history is deleted from that point on, and the +* new attitude states are appended. +* +* \par Examples: +\code + AttitudeState myAttitudeState; + myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1))); + Vector initAngVelVector(3); + initAngVelVector(1) = 0.1; + myAttitudeState.SetAngularVelocity(initAngVelVector); + + AttitudeHistory myAttitudeHistory; // create an attitude history with an empty collection + myAttitudeHistory.AppendHistory(0, myAttitudeState); // add the state myAttitudeState which occured at t=0 to the history + + cout << myAttitudeHistory.GetHistory() << endl; // Get a matrix of the stored state and output + // [t0, attitude parameters @ t=0] + // [t1, attitude parameters @ t=1] + // [t2, attitude parameters @ t=2] etc... +\endcode +*/ +class AttitudeHistory : public History +{ +public: + /*! \brief Constructs an empty attitude history. + */ + AttitudeHistory(); + + /*! \brief Default Deconstructor + */ + ~AttitudeHistory(); + + /*! \brief Add the attitude rotation and angular velocity, which occured at a time in seconds, to the history. + * + * Appends the state at t=_appendTime. if the new state + * occured at a time that is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new state will be appended. + * @param _appendTime time (in seconds) to be added. + * @param _appendRotation the new Rotation describing the attitude to be added (by default the rotation is stored with respect to the inertial frame). + * @param _appendAngVel Angular Velocity vector (3-elements) to be appended. + */ + void AppendHistory(const double &_appendTime, const Rotation &_appendRotation, const Vector &_appendAngVel); + + /*! \brief Add the attitude rotation and angular velocity, which occured with an ssfTime object, to the history. + * + * Appends the state at t=_appendTime. if the new state + * occured at a time that is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new state will be appended. + * @param _appendTime the ssfTime object specifying when the state occured. + * @param _appendRotation the new Rotation describing the attitude to be added (by default the rotation is stored with respect to the inertial frame). + * @param _appendAngVel Angular Velocity vector (3-elements) to be appended. + */ + void AppendHistory(const ssfTime &_appendTime, const Rotation &_appendRotation, const Vector &_appendAngVel); + + /*! \brief Add the attitude state that occured at a time in seconds to the history. + * + * Appends the state at t=_appendTime. if the new state + * occured at a time that is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new state will be appended. + * @param _appendTime time (in seconds) to be added. + * @param _appendAttitudeState the new attitude state to be added. + */ + void AppendHistory(const double &_appendTime, const AttitudeState &_appendAttitudeState); + + /*! \brief Add the attitude state that occured with an ssfTime object to the history. + * + * Appends the state at t=_appendTime. if the new state + * occured at a time that is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new state will be appended. + * @param _appendTime the ssfTime object specifying when the state occured. + * @param _appendAttitudeState the new attitude state to be added. + */ + void AppendHistory(const ssfTime &_appendTime, const AttitudeState &_appendAttitudeState); + + /*! \brief Add a vector of ssfTime and AttitudeState objects to the stored history. + * + * if the beginning of the new state vector occured earlier than + * any of the stored values then the attitude history will be erased + * from the overlap point and the new attitude state vector will be appended. + * @param _appendTime vector of ssfTime objects to be appended. + * @param _appendAttitudeState vector of AttitudeState objects describing the attitude to be appended. + */ + void AppendHistory(const vector &_appendTime, const vector &_appendAttitudeState); + + /*! \brief Add a vector of ssfTime, Rotation, and Angular Velocity vector objects to the stored history. + * + * if the beginning of the new state vector occured earlier than + * any of the stored values then the attitude history will be erased + * from the overlap point and the new attitude state vector will be appended. + * @param _appendTime vector of ssfTime objects to be appended. + * @param _appendRotation vector of Rotation objects describing the attitude to be appended (stores by default with repect to inertial reference frame). + * @param _appendAngVel vector of Angular Velocity vectors (3-elements) to be appended. + */ + void AppendHistory(const vector &_appendTime, const vector &_appendRotation, const vector &_appendAngVel); + + /*! \brief Erases the attitude state history */ + void ResetHistory(); + + /*! \brief Returns a matrix of the attitude state history + * + * returns the matrix of the form: // Get a matrix of the stored state and output + // [t0, attitude parameters @ t=0] + // [t1, attitude parameters @ t=1] + // [t2, attitude parameters @ t=2] etc... + * @param _rotType rotation type to return the state in (ie quaternion, MRP, DCM, Euler Angles, etc.). Default (ie no type specified) to quaternion elements. + * @return nxm matrix of the state history, where n is the number of time states stored and m is the number of elements in the RotationType. + */ + Matrix GetHistory(const RotationType &_rotType = Quaternion_Type); + + /*! \brief Returns the attitude state at the requested time. + * + * \warning Always interpolates using quaternions + * May require interpolation (see Interpolator). + * @param _requestedTime requested state time. If it is not an integrated mesh point, interpolation will be used to determine the approximated value. + * The _requestedTime may be different due to errors (outside state bounds, uncalculable interpolation). + * @param _returnRotation the rotation at the requested time. + * @param _returnAngVelVector the angular velocity vector at the requested time. + */ + void GetState(const ssfTime& _requestedTime, Rotation& _returnRotation, Vector& _returnAngVelVector); + + /*! \brief Returns the Attitude state at the requested time. + * + * \warning Always interpolates using quaternions + * Performs the same functionality as GetState(ssfTime& _requestedTime, Rotation& _returnRotation, Vector& _returnAngVelVector), but returns the attitude state from the + * function rather than by reference. + * @param _requestedTime requested state time. If it is not an integrated mesh point, interpolation will be used to determine the approximated value. + * The _requestedTime may be different due to errors (outside state bounds, uncalculable interpolation). + * @return the attitude state at the requested time + */ + AttitudeState GetState(const ssfTime& _requestedTime); +private: + /*! \brief internal vector container of the AttitudeState objects describing the state history */ + vector m_AttitudeHistory; + /*! \brief internal vector of attitude interpolations */ + vector m_AttitudeInterpolations; + +}; +} // close namespace O_SESSAME + +#endif + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: AttitudeHistory.h,v $ +* Revision 1.11 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.10 2003/05/22 21:01:01 nilspace +* Updated comments. +* +* Revision 1.9 2003/05/20 17:50:01 nilspace +* Updated comments. +* +* Revision 1.8 2003/05/13 18:45:35 nilspace +* Added interpolation functionality. +* +* Revision 1.7 2003/05/01 23:59:48 nilspace +* Commented the API. +* +* Revision 1.6 2003/04/29 20:57:46 nilspace +* Updated to work with Propagator. +* +* Revision 1.5 2003/04/28 20:11:52 nilspace +* Made Quaternion_Type the default GetHistory rotation return type. +* +* Revision 1.4 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.3 2003/04/23 17:00:47 nilspace +* Changed to work with AttitudeState and not Rotation and AngVel seperately. +* Time is now stored as ssfTime. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/03/27 20:29:20 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/datahandling/CVS/Entries b/src/datahandling/CVS/Entries new file mode 100644 index 0000000..7babf54 --- /dev/null +++ b/src/datahandling/CVS/Entries @@ -0,0 +1,10 @@ +/AttitudeHistory.cpp/1.10/Tue May 27 17:35:52 2003// +/AttitudeHistory.h/1.11/Sat Oct 18 21:37:27 2003// +/History.cpp/1.11/Sat Oct 18 21:37:27 2003// +/History.h/1.14/Sat Oct 18 21:37:27 2003// +/Jamfile/1.3/Mon Dec 8 14:48:27 2003// +/Makefile/1.9/Sat Oct 18 21:37:27 2003// +/OrbitHistory.cpp/1.7/Thu May 22 21:01:31 2003// +/OrbitHistory.h/1.7/Thu May 22 21:01:31 2003// +/datahandling.pro/1.6/Sat Oct 18 21:37:27 2003// +D diff --git a/src/datahandling/CVS/Repository b/src/datahandling/CVS/Repository new file mode 100644 index 0000000..5f5b773 --- /dev/null +++ b/src/datahandling/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/datahandling diff --git a/src/datahandling/CVS/Root b/src/datahandling/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/datahandling/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/datahandling/History.cpp b/src/datahandling/History.cpp new file mode 100644 index 0000000..ec64f4a --- /dev/null +++ b/src/datahandling/History.cpp @@ -0,0 +1,201 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file History.cpp +* \brief Encapsulation of History memento object. +* \author $Author: rsharo $ +* \version $Revision: 1.11 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "History.h" +#include "utils/LinearInterpolator.h" +namespace O_SESSAME { + +History::History() : m_OriginalInterpolator(new LinearInterpolator) +{ + ResetHistory(); + m_TimeHistory.reserve(HISTORY_RESERVE_SIZE); + m_TimeInterpolations.reserve(HISTORY_RESERVE_SIZE); + m_TimeInterpolations.front() = NULL; +} + +History::~History() +{ + // delete the old interpolator + if(m_OriginalInterpolator) + delete m_OriginalInterpolator; +} + +void History::AppendHistory(const double &_appendTime) +{ + AppendHistory(ssfTime(_appendTime)); +} +void History::AppendHistory(const ssfTime &_appendTime) +{ + m_TimeHistory.push_back(_appendTime); +} + +vector::difference_type History::AppendHistory(const vector &_appendTime) +{ + vector::const_iterator iter; + + // Determine if there is already a time history that overlaps with the appending time + vector::iterator replacementTime = std::find_if(m_TimeHistory.begin(), m_TimeHistory.end(), bind2nd(greater_equal(), *(_appendTime.begin()))); + vector::difference_type retDistance = 0; + + // If there is an overlap, delete the times following the overlap point. + if(replacementTime != m_TimeHistory.end()) + { + // Store the distance from the overlapping point to the end & then delete the overlap. + retDistance = distance(replacementTime, m_TimeHistory.end()); + m_TimeHistory.erase(replacementTime, m_TimeHistory.end()); + } + // Append the new times to the time history. + for(iter = _appendTime.begin(); iter != _appendTime.end(); ++iter) + m_TimeHistory.push_back(*iter); + + return retDistance; +} + +void History::ResetHistory() +{ + vector newTime(0); + m_TimeHistory.swap(newTime); + return; +} + +Matrix History::GetHistory() +{ + Matrix returnMatrix(m_TimeHistory.size(), 1); + int ii = 0; + vector::const_iterator iter; + for(iter = m_TimeHistory.begin(); iter != m_TimeHistory.end(); ++iter) + { + returnMatrix(MatrixIndexBase + ii, MatrixIndexBase) = iter->GetSeconds(); + ++ii; + } + + return returnMatrix; + +} + +vector::difference_type History::GetState(const ssfTime& _requestedTime) +{ + // Find the nearest (lower) corresponding time point + vector::iterator nearestTimeIterator = find_if(m_TimeHistory.begin(), m_TimeHistory.end(), bind2nd(greater_equal(), _requestedTime)); + // Store the distance from the first matching data point to the end + vector::difference_type nearestTimeIndex = distance(m_TimeHistory.begin(), nearestTimeIterator); + + /* The code commented out below was a model for interpolation in the derived classes. It is not needed, but + was left to verify against for the time being. nilspace:(13.5.03) + int numDataPoints = 0; + if(m_OriginalInterpolator) + numDataPoints = m_OriginalInterpolator->GetNumberDataPoints(); + else + return nearestTimeIndex; + Vector timeVector(numDataPoints); + Matrix dataMatrix(numDataPoints, 1); + + // See if there is data at the requested time. + if((*nearestTimeIterator != _requestedTime) && (nearestTimeIterator != m_TimeHistory.end())) + { + // Determine if there is currently an interpolation through the requested point. + // if there isn't, create one, then evaluate the interpolation at the requested data point. + while(m_TimeInterpolations.capacity() < nearestTimeIndex) + { + m_TimeInterpolations.reserve(m_TimeInterpolations.capacity() + HISTORY_RESERVE_SIZE); + } + if(!m_TimeInterpolations[nearestTimeIndex]) + { + + // fill in the 'missing' interpolations + for(int kk = m_TimeInterpolations.size(); kk < nearestTimeIndex; ++kk) + m_TimeInterpolations.push_back(m_OriginalInterpolator->NewPointer()); + + m_TimeInterpolations.push_back(m_OriginalInterpolator->NewPointer()); + } + // Calculate the interpolation parameters if necessary + if(!m_TimeInterpolations[nearestTimeIndex]->GetValid()) + { + for(int ii = 1; ii <= numDataPoints; ++ii) + { + timeVector(ii) = m_TimeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetSeconds(); + for(int jj = 1; jj <= dataMatrix[MatrixColsIndex].getIndexBound(); ++jj) + { + dataMatrix(ii,jj) = m_TimeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetSeconds(); + } + } + + m_TimeInterpolations[nearestTimeIndex]->Interpolate(timeVector, dataMatrix); + } + + _requestedTime.Set(m_TimeInterpolations[nearestTimeIndex]->Evaluate(_requestedTime.GetSeconds())(1)); + + } + else if((nearestTimeIterator == m_TimeHistory.begin()) || (nearestTimeIterator == m_TimeHistory.end())) + { // the requested time isn't in the stored interval + return (nearestTimeIndex = -1); + } + else + { // there happens to be meshpoint data at the requested time, return it. + _requestedTime = *nearestTimeIterator; + } + */ + return nearestTimeIndex; +} + +void History::SetInterpolator(Interpolator* _newInterpolator) +{ + // delete the old interpolator + if(m_OriginalInterpolator) + delete m_OriginalInterpolator; + + // make a copy of the new base interpolator + m_OriginalInterpolator = _newInterpolator->Clone(); +} + +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: History.cpp,v $ +* Revision 1.11 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.10 2003/05/22 21:01:44 nilspace +* Updated comments. +* +* Revision 1.9 2003/05/20 17:50:01 nilspace +* Updated comments. +* +* Revision 1.8 2003/05/15 18:10:50 nilspace +* Fixed the constructor initialize error of an extra , +* +* Revision 1.7 2003/05/13 18:45:35 nilspace +* Added interpolation functionality. +* +* Revision 1.6 2003/05/01 18:24:36 nilspace +* Prevented overlapping Appends by removing the old states and times. +* +* Revision 1.5 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/25 17:14:59 nilspace +* Added OrbitHistory & made sure it builds. +* Moved Appending time to History.cpp. +* +* Revision 1.3 2003/04/23 17:01:02 nilspace +* Time is now stored as an ssfTime object. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/03/27 20:29:02 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/datahandling/History.h b/src/datahandling/History.h new file mode 100644 index 0000000..ad39adf --- /dev/null +++ b/src/datahandling/History.h @@ -0,0 +1,193 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file History.h +* \brief Interface to the abstract History class. +* \author $Author: rsharo $ +* \version $Revision: 1.14 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __HISTORY_H__ +#define __HISTORY_H__ +#include +#include +#include +#include "utils/Time.h" +#include "utils/Interpolator.h" +using namespace std; +namespace O_SESSAME { +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup DataHandling Data Handling +* This toolbox includes all the functionality regarding the handling, storage, importing, and +* exporting of data from the spacecraft simulation environment. The primary classes include the +* History class and its derived classes. These History objects store various spacecraft states and +* provide for various manipulations of the data. +* +* \par Extension Points: +* +*/ + +/*! @defgroup StateHistory State History +* \ingroup DataHandling +*/ +#define HISTORY_RESERVE_SIZE 1000 /*!< \brief expected history storage size. Used to reserve memory of states ahead of time. This number should be characteristic of the typical number of states in a history matrix. */ +/*! \brief Base class for histories storing state variables, also stores time states. +* \ingroup StateHistory +* +* The History class provides a common interface for the group of classes which +* store previous state information. The user can append new state information, +* output the current state history, or reset the entire history. If the user appends +* a time which earlier than the end of the current history, the current history +* is deleted from that point on, and the new time is appended. +* The History class also provides the common storage of the time history. +* +* \par Examples: +\code +History myHistory; // create a history with an empty collection +myHistory.AppendHistory(0); // add 0 seconds to the history +myHistory.ResetHistory(); // reset the history to an empty collection +myHistory.AppendHistory(10);// add 10 seconds to the history + +cout << myHistory.GetHistory() << endl; // Get a matrix of the stored times and output +\endcode +*/ +class History +{ +public: + /*! \brief Creates an instance of History. + */ + History(); + + /*! \brief Default Deconstructor + */ + virtual ~History(); + + /*! \brief Add a time (in seconds) to the stored history. + * + * if the new time is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new value will be appended. + * @param _appendTime time (in seconds) to be added. + */ + virtual void AppendHistory(const double &_appendTime); + + /*! \brief Add an ssfTime object to the stored history. + * + * if the new time is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new value will be appended. + * @param _appendTime an ssfTime object to be appended. + */ + virtual void AppendHistory(const ssfTime &_appendTime); + + /*! \brief Add a vector of ssfTime objects to the stored history. + * + * if the beginning of the new time vector is earlier than + * any of the stored values then the time history will be erased + * from the overlap point and the new time vector will be appended. + * @param _appendTime vector of ssfTime objects to be appended. + */ + virtual vector::difference_type AppendHistory(const vector &_appendTime); + + /*! \brief Erases the time history */ + void ResetHistory(); + + /*! \brief Returns a matrix of the time history + * @return nx1 matrix of the state history, where n is the number of time states stored. + */ + virtual Matrix GetHistory(); + + /*! \brief Returns the nearest stored,lower mesh point to the requested time. + * + * interpolates using the specified interpolator if necessary. + * @param _requestedTime Desired time to retrieve the state. Used to find the nearest corresponding + * lower mesh point. + * @return The index of the time history vector of the nearest, lower mesh point. + */ + + /*! \brief Sets the interpolator used for calculating the states in-between stored mesh points. + * @param _newInterpolator pointer to the interpolator that serves as the model type for all the + * interpolations between meshpoints. + */ + virtual void SetInterpolator(Interpolator* _newInterpolator); + +protected: + /*! \brief Returns the nearest stored,lower mesh point to the requested time. + * + * interpolates using the specified interpolator if necessary. + * @param _requestedTime Desired time to retrieve the state. Used to find the nearest corresponding + * lower mesh point. + * @return The index of the time history vector of the nearest, lower mesh point. + */ + vector::difference_type GetState(const ssfTime& _requestedTime); + + /*! \brief internal vector container of the ssfTime objects describing the state history */ + vector m_TimeHistory; + + /*! \brief internal storage of the original, nominal interpolator to be copied and used for all interpolations */ + Interpolator* m_OriginalInterpolator; + + /*! \brief internal vector of time interpolations */ + vector m_TimeInterpolations; + + +}; + +} // close namespace O_SESSAME + +#endif + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: History.h,v $ +* Revision 1.14 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.13 2003/06/06 00:34:16 nilspace +* ? +* +* Revision 1.12 2003/05/27 17:35:52 nilspace +* Updated to prevent errors. +* +* Revision 1.11 2003/05/22 21:01:45 nilspace +* Updated comments. +* +* Revision 1.10 2003/05/20 17:50:01 nilspace +* Updated comments. +* +* Revision 1.9 2003/05/15 18:10:24 nilspace +* Added and to the include files. +* +* Revision 1.8 2003/05/13 18:45:35 nilspace +* Added interpolation functionality. +* +* Revision 1.7 2003/05/01 23:59:48 nilspace +* Commented the API. +* +* Revision 1.6 2003/05/01 18:24:36 nilspace +* Prevented overlapping Appends by removing the old states and times. +* +* Revision 1.5 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/25 17:15:00 nilspace +* Added OrbitHistory & made sure it builds. +* Moved Appending time to History.cpp. +* +* Revision 1.3 2003/04/23 17:01:02 nilspace +* Time is now stored as an ssfTime object. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/03/27 20:29:02 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/datahandling/Jamfile b/src/datahandling/Jamfile new file mode 100644 index 0000000..7a60bef --- /dev/null +++ b/src/datahandling/Jamfile @@ -0,0 +1,30 @@ +########################################### +# Datahandling Jamfile +# +# $Author: simpliciter $ +# $Revision: 1.3 $ +# $Date: 2003/12/08 14:48:27 $ +########################################### + +SubDir OPENSESSAME_ROOT src datahandling ; + +Objects History.cpp AttitudeHistory.cpp OrbitHistory.cpp ; +ObjectHdrs History.cpp AttitudeHistory.cpp OrbitHistory.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)datahandling : History$(SUFOBJ) AttitudeHistory$(SUFOBJ) OrbitHistory$(SUFOBJ) ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)datahandling$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : History.h AttitudeHistory.h OrbitHistory.h ; + + + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.3 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# ******************************************************************************/ + + diff --git a/src/datahandling/Makefile b/src/datahandling/Makefile new file mode 100644 index 0000000..5111b69 --- /dev/null +++ b/src/datahandling/Makefile @@ -0,0 +1,180 @@ +############################################################################# +# Makefile for building: ../../lib/libosessame_datahandling.a +# Generated by qmake (1.02a) on: Sat Oct 18 17:32:57 2003 +# Project: datahandling.pro +# Template: lib +# Command: $(QMAKE) datahandling.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +LEX = flex +YACC = yacc +CFLAGS = -pipe -Wall -W -g +CXXFLAGS = -pipe -Wall -W -g +LEXFLAGS = +YACCFLAGS= -d +INCPATH = -I../matrix -I../rotation -I../attitude -I../orbit -I../datahandling -I../dynamics -I../environment -I.. -I$(QTDIR)/mkspecs/default +AR = ar cqs +RANLIB = +MOC = $(QTDIR)/bin/moc +UIC = $(QTDIR)/bin/uic +QMAKE = qmake +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE= $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = +DEL_DIR = +MOVE = mv + +####### Output directory + +OBJECTS_DIR = ../../objects/ + +####### Files + +HEADERS = AttitudeHistory.h \ + History.h \ + OrbitHistory.h +SOURCES = AttitudeHistory.cpp \ + History.cpp \ + OrbitHistory.cpp +OBJECTS = ../../objects/AttitudeHistory.o \ + ../../objects/History.o \ + ../../objects/OrbitHistory.o +FORMS = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = +DIST = +QMAKE_TARGET = osessame_datahandling +DESTDIR = ../../lib/ +TARGET = ../../lib/libosessame_datahandling.a + +first: all +####### Implicit rules + +.SUFFIXES: .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: Makefile $(TARGET) + +staticlib: $(TARGET) + +$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) + test -d ../../lib/ || mkdir -p ../../lib/ + -rm -f $(TARGET) + $(AR) $(TARGET) $(OBJECTS) $(OBJMOC) + + +mocables: $(SRCMOC) + +$(MOC): + ( cd $(QTDIR)/src/moc ; $(MAKE) ) + +Makefile: datahandling.pro $(QTDIR)/mkspecs/default/qmake.conf + $(QMAKE) datahandling.pro +qmake: + @$(QMAKE) datahandling.pro + +dist: + @mkdir -p ../../objects/osessame_datahandling && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) ../../objects/osessame_datahandling/ && ( cd `dirname ../../objects/osessame_datahandling` && $(TAR) osessame_datahandling.tar osessame_datahandling && $(GZIP) osessame_datahandling.tar ) && mv `dirname ../../objects/osessame_datahandling`/osessame_datahandling.tar.gz . && rm -rf ../../objects/osessame_datahandling + +uiclean: + +clean: + -rm -f $(OBJECTS) + -rm -f *~ core *.core + + +####### Sub-libraries + +distclean: clean + -rm -f ../../lib/$(TARGET) $(TARGET) + + +FORCE: + +####### Compile + +../../objects/AttitudeHistory.o: AttitudeHistory.cpp AttitudeHistory.h \ + ../rotation/Rotation.h \ + ../attitude/AttitudeState.h \ + History.h \ + ../matrix/Matrix.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/AttitudeHistory.o AttitudeHistory.cpp + +../../objects/History.o: History.cpp History.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/History.o History.cpp + +../../objects/OrbitHistory.o: OrbitHistory.cpp OrbitHistory.h \ + ../matrix/Matrix.h \ + ../rotation/Rotation.h \ + History.h \ + ../orbit/OrbitState.h \ + ../orbit/orbitstaterep/PositionVelocity.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/OrbitHistory.o OrbitHistory.cpp + +####### Install + +install: all + +uninstall: + diff --git a/src/datahandling/OrbitHistory.cpp b/src/datahandling/OrbitHistory.cpp new file mode 100644 index 0000000..8d1366e --- /dev/null +++ b/src/datahandling/OrbitHistory.cpp @@ -0,0 +1,169 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitHistory.cpp +* \brief Encapsulation of Orbit History memento object. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/05/22 21:01:31 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "OrbitHistory.h" +namespace O_SESSAME { + +OrbitHistory::OrbitHistory() +{ + ResetHistory(); + m_OrbitHistory.reserve(HISTORY_RESERVE_SIZE); + m_OrbitInterpolations.reserve(HISTORY_RESERVE_SIZE); +} + +void OrbitHistory::AppendHistory(const double &_appendTime, const OrbitState &_appendOrbitState) +{ + AppendHistory(ssfTime(_appendTime), _appendOrbitState); +} + +void OrbitHistory::AppendHistory(const ssfTime &_appendTime, const OrbitState &_appendOrbitState) +{ + History::AppendHistory(_appendTime); + m_OrbitHistory.push_back(_appendOrbitState); + return; +} + +void OrbitHistory::AppendHistory(const vector &_appendTime, const vector &_appendOrbitState) +{ + vector::const_iterator iter; + // History::AppendHistory returns the distance from the end over any overlapping states. + vector::difference_type retDistance = History::AppendHistory(_appendTime); + + // If there is an overlap, delete the orbit states following the overlap point. + if(retDistance != 0) + m_OrbitHistory.erase(m_OrbitHistory.end()-retDistance, m_OrbitHistory.end()); + + // Append the new states to the orbit history. + for(iter = _appendOrbitState.begin(); iter != _appendOrbitState.end(); ++iter) + m_OrbitHistory.push_back(*iter); + + return; +} + +void OrbitHistory::ResetHistory() +{ + vector newOrbit(0); + m_OrbitHistory.swap(newOrbit); + History::ResetHistory(); + return; +} + + +Matrix OrbitHistory::GetHistory() +{ + /*! \todo Grab the history depending on the desired state return type (elements, position, velocity, etc.) */ + // initialize the output matrix based on the size of the desired output state, + // and an element for time. The number of rows is equal to the number of time elements. + int OrbitVectorSize = (m_OrbitHistory.back()).GetState().getIndexBound(); + Matrix returnMatrix(m_TimeHistory.size(), 1 + OrbitVectorSize); + + for(int ii = 0; ii < m_TimeHistory.size(); ii++) + { + returnMatrix(MatrixIndexBase + ii, MatrixIndexBase) = m_TimeHistory[ii].GetSeconds(); + returnMatrix(MatrixIndexBase + ii, _(MatrixIndexBase+1,MatrixIndexBase + OrbitVectorSize)) = ~m_OrbitHistory[ii].GetState(); + } + return returnMatrix; +} +OrbitState OrbitHistory::GetState(const ssfTime& _requestedTime) +{ + OrbitState tempOrbState; + GetState(_requestedTime, tempOrbState); + return tempOrbState; +} +void OrbitHistory::GetState(const ssfTime& _requestedTime, OrbitState& _returnOrbitState) +{ + // History::GetState returns the index of the nearest state. + vector::difference_type nearestTimeIndex = History::GetState(_requestedTime); + + int numDataPoints = 0; + if(m_OriginalInterpolator) + numDataPoints = m_OriginalInterpolator->GetNumberDataPoints(); + else /*! \todo implement better error handling strategy */ + return; + Vector timeVector(numDataPoints); + Matrix dataMatrix(numDataPoints, NUM_POSVEL_ELEMENTS); + Vector tempVector(NUM_POSVEL_ELEMENTS); + + // See if there is data at the requested time. + if(m_TimeHistory[nearestTimeIndex] != _requestedTime) + { + // Determine if there is currently an interpolation through the requested point. + // if there isn't, create one, then evaluate the interpolation at the requested data point. + while(m_OrbitInterpolations.capacity() < nearestTimeIndex) + { + m_OrbitInterpolations.reserve(m_OrbitHistory.capacity() + HISTORY_RESERVE_SIZE); + } + // Check to see if the data is initialized to hold an interpolation + if(!m_OrbitInterpolations[nearestTimeIndex]) + { + // fill in the 'missing' interpolations + for(int kk = m_OrbitInterpolations.size(); kk < nearestTimeIndex; ++kk) + m_OrbitInterpolations.push_back(m_OriginalInterpolator->NewPointer()); + + m_OrbitInterpolations.push_back(m_OriginalInterpolator->NewPointer()); + } + // Calculate the interpolation parameters if necessary + if(!m_OrbitInterpolations[nearestTimeIndex]->GetValid()) + { + for(int ii = 1; ii <= numDataPoints; ++ii) + { + timeVector(ii) = m_TimeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetSeconds(); + dataMatrix(ii,_) = ~m_OrbitHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetStateRepresentation()->GetPositionVelocity(); + } + + m_OrbitInterpolations[nearestTimeIndex]->Interpolate(timeVector, dataMatrix); + } + + tempVector = m_OrbitInterpolations[nearestTimeIndex]->Evaluate(_requestedTime.GetSeconds()); + _returnOrbitState.SetStateRepresentation(new PositionVelocity); + _returnOrbitState.GetStateRepresentation()->SetPositionVelocity(tempVector); + + // Set the returned orbit frame to the same as the history's stored orbit states. + _returnOrbitState.SetOrbitFrame((m_OrbitHistory.front()).GetOrbitFrame()); + } + else + { // there happens to be meshpoint data at the requested time, return it. + _returnOrbitState = m_OrbitHistory[nearestTimeIndex]; + } + + return; +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitHistory.cpp,v $ +* Revision 1.7 2003/05/22 21:01:31 nilspace +* Updated comments and added SetOrbitRepresentation(new PositionVelocity). +* +* Revision 1.6 2003/05/20 17:50:01 nilspace +* Updated comments. +* +* Revision 1.5 2003/05/13 18:45:35 nilspace +* Added interpolation functionality. +* +* Revision 1.4 2003/05/01 18:24:36 nilspace +* Prevented overlapping Appends by removing the old states and times. +* +* Revision 1.3 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/25 17:15:00 nilspace +* Added OrbitHistory & made sure it builds. +* Moved Appending time to History.cpp. +* +* Revision 1.1 2003/04/25 13:39:08 nilspace +* Initial Submission. +* +* Revision 1.1 2003/03/27 20:29:19 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/datahandling/OrbitHistory.h b/src/datahandling/OrbitHistory.h new file mode 100644 index 0000000..e1e69db --- /dev/null +++ b/src/datahandling/OrbitHistory.h @@ -0,0 +1,162 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitHistory.h +* \brief Interface to the Orbit History class. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/05/22 21:01:31 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __ORBIT_HISTORY_H__ +#define __ORBIT_HISTORY_H__ + +#include "Matrix.h" +#include "Rotation.h" +#include "History.h" +#include "OrbitState.h" +#include "orbitstaterep/PositionVelocity.h" +#include +using namespace std; +namespace O_SESSAME { + +/*! \brief Class for storing a time history of orbital states. +* \ingroup StateHistory +* +* The OrbitHistory class provides a container of previous OrbitState objects. The user +* may append new states, reset the collection of states, or return the orbit history +* in a matrix. If the user appends orbit states at time which earlier than the end +* of the current history, the current history is deleted from that point on, and the +* new orbit states are appended. +* +* \par Examples: +\code + OrbitState myOrbitState; + myOrbitState.SetStateRepresentation(new PositionVelocity); + myOrbitState.SetOrbitFrame(new OrbitFrameIJK); + Vector initPV(6); + myOrbitState.SetState(initPV); + myOrbit->SetStateObject(myOrbitState); + + OrbitHistory myOrbitHistory; // create an orbit history with an empty collection + myOrbitHistory.AppendHistory(0, myOrbitState); // add the state myOrbitState which occured at t=0 to the history + + cout << myOrbitHistory.GetHistory() << endl; // Get a matrix of the stored state and output + // [t0, orbit elements @ t=0] + // [t1, orbit elements @ t=1] + // [t2, orbit elements @ t=2] etc... +\endcode +*/ +class OrbitHistory : public History +{ +public: + /*! \brief Default Constructor + */ + OrbitHistory(); + + /*! \brief Add the orbit state that occured at a time in seconds to the history. + * + * Appends the state at t=_appendTime. if the new state + * occured at a time that is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new state will be appended. + * @param _appendTime time (in seconds) to be added. + * @param _appendOrbitState the new orbital state to be added. + */ + void AppendHistory(const double &_appendTime, const OrbitState &_appendOrbitState); + + /*! \brief Add the orbit state that occured with an ssfTime object to the history. + * + * Appends the state at t=_appendTime. if the new state + * occured at a time that is earlier than any of the stored values + * then the time history will be erased from the overlap point + * and the new state will be appended. + * @param _appendTime the ssfTime object specifying when the state occured. + * @param _appendOrbitState the new orbital state to be added. + */ + void AppendHistory(const ssfTime &_appendTime, const OrbitState &_appendOrbitState); + + /*! \brief Add a vector of ssfTime and OrbitState objects to the stored history. + * + * if the beginning of the new state vector occured earlier than + * any of the stored values then the orbit history will be erased + * from the overlap point and the new orbit state vector will be appended. + * @param _appendTime vector of ssfTime objects to be appended. + * @param _appendOrbitState vector of OrbitState objects to be appended. + */ + void AppendHistory(const vector &_appendTime, const vector &_appendOrbitState); + + /*! \brief Erases the orbit state history */ + void ResetHistory(); + + /*! \brief Returns a matrix of the orbit state history + * + * returns the matrix of the form: // Get a matrix of the stored state and output + // [t0, orbit elements @ t=0] + // [t1, orbit elements @ t=1] + // [t2, orbit elements @ t=2] etc... + * @return nxm matrix of the state history, where n is the number of time states stored and m is the number of elements in the OrbitStateRepresentation. + */ + Matrix GetHistory(); + + /*! \brief Returns the Orbit state at the requested time. + * \warning Always interpolates using position \& velocity. + * + * May require interpolation (see Interpolator). + * @param _requestedTime requested state time. If it is not an integrated mesh point, interpolation will be used to determine the approximated value. + * The _requestedTime may be different due to errors (outside state bounds, uncalculable interpolation). + * @param _returnOrbitState the orbital state at the requested time (the requested time @em may be different due to errors) + */ + void GetState(const ssfTime& _requestedTime, OrbitState& _returnOrbitState); + + /*! \brief Returns the Orbit state at the requested time. + * \warning Always interpolates using position \& velocity. + * + * Performs the same functionality as GetState(ssfTime& _requestedTime, OrbitState& _returnOrbitState), but returns the orbit state from the + * function rather than by reference. + * @param _requestedTime requested state time. If it is not an integrated mesh point, interpolation will be used to determine the approximated value. + * The _requestedTime may be different due to errors (outside state bounds, uncalculable interpolation). + * @return the orbital state at the requested time (the requested time @em may be different due to errors) + */ + OrbitState GetState(const ssfTime& _requestedTime); +private: + /*! \brief internal vector container of the OrbitState objects describing the state history */ + vector m_OrbitHistory; + /*! \brief internal vector of orbit interpolations */ + vector m_OrbitInterpolations; +}; +} // close namespace O_SESSAME + +#endif + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitHistory.h,v $ +* Revision 1.7 2003/05/22 21:01:31 nilspace +* Updated comments and added SetOrbitRepresentation(new PositionVelocity). +* +* Revision 1.6 2003/05/20 17:50:01 nilspace +* Updated comments. +* +* Revision 1.5 2003/05/13 18:45:35 nilspace +* Added interpolation functionality. +* +* Revision 1.4 2003/05/01 23:59:48 nilspace +* Commented the API. +* +* Revision 1.3 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/25 17:15:00 nilspace +* Added OrbitHistory & made sure it builds. +* Moved Appending time to History.cpp. +* +* Revision 1.1 2003/04/25 13:39:09 nilspace +* Initial Submission. +* +* Revision 1.1 2003/03/27 20:29:20 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/datahandling/datahandling.pro b/src/datahandling/datahandling.pro new file mode 100644 index 0000000..2bb9914 --- /dev/null +++ b/src/datahandling/datahandling.pro @@ -0,0 +1,27 @@ +# +# $Id: datahandling.pro,v 1.6 2003/10/18 21:37:27 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = AttitudeHistory.h History.h OrbitHistory.h +SOURCES = AttitudeHistory.cpp History.cpp OrbitHistory.cpp +TARGET = osessame_datahandling +VERSION = 1.0 + + +DESTDIR = ../../lib/ +INCLUDEPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment .. +CONFIG = staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment ../utils diff --git a/src/dynamics/AnalyticPropagator.h b/src/dynamics/AnalyticPropagator.h new file mode 100644 index 0000000..2044d48 --- /dev/null +++ b/src/dynamics/AnalyticPropagator.h @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file AnalyticPropagator.h +* \brief Interface to the Analytic Propagator class. +* \author $Author: nilspace $ +* \version $Revision: 1.5 $ +* \date $Date: 2003/05/13 18:54:14 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Finish documentation +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ANALYTIC_PROPAGATOR_H__ +#define __SSF_ANALYTIC_PROPAGATOR_H__ + +#include "Rotation.h" + +namespace O_SESSAME { + +/*! \brief Encapsulation of the propagation of the spacecraft dynamics (attitude, orbital, etc.) +* \ingroup PropagatorToolkit +* +* \detail The propagator is used to tie together the various spacecraft dynamics that are desired to be +* propagated. The user has the ability to set the time derivative equations, integrators, parameters, +* etc. as necessary. Furthermore, the Propagator class can be derived for more functionality. +*/ +class AnalyticPropagator : public Propagator +{ +public: + /** Default Constructor */ + AnalyticPropagator(); + + /** Propagates the dynamics forward through time + * @param _propTime STL vector of values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + */ + virtual void Propagate(const vector &_propTime); + +private: + +}; +} +#endif +/***************************************************************************** +* $Log: AnalyticPropagator.h,v $ +* Revision 1.5 2003/05/13 18:54:14 nilspace +* Fixed comments. +* +* Revision 1.4 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.3 2003/04/25 13:43:51 nilspace +* Updated to actually work. Still needs verification. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:51:58 nilspace +* Initial submission. Only a template, needs to be implemented. +* +******************************************************************************/ diff --git a/src/dynamics/CVS/Entries b/src/dynamics/CVS/Entries new file mode 100644 index 0000000..aa00e0f --- /dev/null +++ b/src/dynamics/CVS/Entries @@ -0,0 +1,11 @@ +/AnalyticPropagator.h/1.5/Tue May 13 18:54:14 2003// +/CombinedNumericPropagator.cpp/1.5/Tue Jun 10 02:24:03 2003// +/CombinedNumericPropagator.h/1.4/Sat Oct 18 21:37:27 2003// +/Jamfile/1.3/Mon Dec 8 14:48:27 2003// +/NumericPropagator.cpp/1.8/Tue May 20 17:55:35 2003// +/NumericPropagator.h/1.8/Sat Oct 18 21:37:27 2003// +/Propagator.cpp/1.7/Tue Jun 10 02:24:04 2003// +/Propagator.h/1.11/Sat Oct 18 21:37:27 2003// +/QuaternionDynamics.h/1.3/Wed Apr 23 16:30:58 2003// +/dynamics.pro/1.3/Sat Oct 18 21:37:28 2003// +D diff --git a/src/dynamics/CVS/Repository b/src/dynamics/CVS/Repository new file mode 100644 index 0000000..761709f --- /dev/null +++ b/src/dynamics/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/dynamics diff --git a/src/dynamics/CVS/Root b/src/dynamics/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/dynamics/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/dynamics/CombinedNumericPropagator.cpp b/src/dynamics/CombinedNumericPropagator.cpp new file mode 100644 index 0000000..1c20dca --- /dev/null +++ b/src/dynamics/CombinedNumericPropagator.cpp @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file CombinedNumericPropagator.cpp +* \brief Implementation of the Combined Numeric Propagator class. +* \author $Author: nilspace $ +* \version $Revision: 1.5 $ +* \date $Date: 2003/06/10 02:24:03 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "CombinedNumericPropagator.h" +namespace O_SESSAME { + +CombinedNumericPropagator::CombinedNumericPropagator() +{ + +} + +CombinedNumericPropagator::~CombinedNumericPropagator() +{ + /*! \todo figure out how to delete m_pIntegrator only when it is not being used */ + if(m_pOrbitIntegrator) + delete m_pOrbitIntegrator; + if(m_pAttitudeIntegrator) + delete m_pAttitudeIntegrator; +} + +void CombinedNumericPropagator::Propagate(const vector &_propTime, const Vector &_orbitInitConditions, const Vector &_attInitConditions) +{ + /** \todo Determine what prop times exist and what times are req'd to recalc */ + + // Test to see if propagation is 'too long' & needs to be broken up + + + // Propagate the orbit & attitude, store in the matrix of integration meshpoints + if(m_pOrbitObject) + if (m_pOrbitObject->IsIntegrateable()) + PropagateOrbit(_propTime, _orbitInitConditions); + if(m_pAttitudeObject) + if (m_pAttitudeObject->IsIntegrateable()) + PropagateAttitude(_propTime, _attInitConditions); + + return; +} + +Matrix CombinedNumericPropagator::PropagateOrbit(const vector &_propTime, const Vector &_initConditions) +{ + // Create temporary orbit & attitude that have the same types (copy of) the current state objects + // the actual state vectors will be replaced, but we need to make sure to have the same + // representation & frame types + static OrbitState tempOrbit = m_pOrbitObject->GetStateObject(); + static vector timeVector; timeVector.clear(); // clear since static + static vector orbitVector; orbitVector.clear(); // clear since static + + /*! \todo determine if having vector in Propagate is polymorphic */ + + m_OrbitStateMeshPoints.initialize(m_pOrbitIntegrator->Integrate( + _propTime, + m_pOrbitObject->GetDynamicsEq(), + _initConditions, + m_pOrbitObject, + m_pAttitudeObject, + m_pOrbitObject->GetParameters(), + m_pOrbitObject->GetEnvironmentForcesFunctor() + )); + /** \todo Append the requested time steps in the appropriate component history */ + // Convert the meshpoints to stored objects and append them to the appropriate history. + for (int ii = MatrixIndexBase; ii < m_OrbitStateMeshPoints[MatrixRowsIndex].getIndexBound() + MatrixIndexBase; ++ii) + { + (m_pOrbitObject->GetStateConversion())(m_OrbitStateMeshPoints(ii,_(MatrixIndexBase+1,m_OrbitStateMeshPoints[MatrixColsIndex].getIndexBound())), tempOrbit); + timeVector.push_back(ssfTime(m_OrbitStateMeshPoints(ii,MatrixIndexBase))); + orbitVector.push_back(tempOrbit); + } + + // Store the new histories to the orbit & attitude objects + if(m_pOrbitObject) + m_pOrbitObject->GetHistoryObject().AppendHistory(timeVector, orbitVector); + + // Set the stored Attitude & Orbit + /*! \todo Determine if the updated attitude & orbit should be set in Propagator */ + m_pOrbitObject->SetStateObject(tempOrbit); + + return m_OrbitStateMeshPoints; +} + +Matrix CombinedNumericPropagator::PropagateAttitude(const vector &_propTime, const Vector &_initConditions) +{ + // Create temporary orbit & attitude that have the same types (copy of) the current state objects + // the actual state vectors will be replaced, but we need to make sure to have the same + // representation & frame types + static AttitudeState tempAttitude = m_pAttitudeObject->GetStateObject(); + static vector timeVector; timeVector.clear(); // clear since static + static vector attitudeVector; attitudeVector.clear(); // clear since static + + static OrbitState tempOrbit = m_pOrbitObject->GetStateObject(); + + m_AttitudeStateMeshPoints.initialize(m_pAttitudeIntegrator->Integrate( + _propTime, + m_pAttitudeObject->GetDynamicsEq(), + _initConditions, + m_pOrbitObject, + m_pAttitudeObject, + m_pAttitudeObject->GetParameters(), + m_pAttitudeObject->GetEnvironmentForcesFunctor() + )); + + /** \todo Append the requested time steps in the appropriate component history */ + // Convert the meshpoints to stored objects and append them to the appropriate history. + for (int ii = MatrixIndexBase; ii < m_AttitudeStateMeshPoints[MatrixRowsIndex].getIndexBound() + MatrixIndexBase; ++ii) + { + (m_pAttitudeObject->GetStateConversion())(m_AttitudeStateMeshPoints(ii,_(MatrixIndexBase+1,m_AttitudeStateMeshPoints[MatrixColsIndex].getIndexBound())), tempAttitude); + timeVector.push_back(ssfTime(m_AttitudeStateMeshPoints(ii,MatrixIndexBase))); + attitudeVector.push_back(tempAttitude); + } + + // Store the new histories to the attitude object + m_pAttitudeObject->GetHistoryObject().AppendHistory(timeVector, attitudeVector); + + // Set the stored Attitude + m_pAttitudeObject->SetStateObject(tempAttitude); + + return m_AttitudeStateMeshPoints; +} + +void CombinedNumericPropagator::SetOrbitIntegrator(Integrator* _pOrbitIntegrator) +{ + m_pOrbitIntegrator = _pOrbitIntegrator; + return; +} +void CombinedNumericPropagator::SetAttitudeIntegrator(Integrator* _pAttitudeIntegrator) +{ + m_pAttitudeIntegrator = _pAttitudeIntegrator; + return; +} +Integrator* CombinedNumericPropagator::GetOrbitIntegrator() const +{ + return m_pOrbitIntegrator; +} +Integrator* CombinedNumericPropagator::GetAttitudeIntegrator() const +{ + return m_pAttitudeIntegrator; +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: CombinedNumericPropagator.cpp,v $ +* Revision 1.5 2003/06/10 02:24:03 nilspace +* Updated moving of StateConversion functions to Attitude and Orbit. +* +* Revision 1.4 2003/05/27 17:36:24 nilspace +* Updated to handle different integration stepsizes. +* +* Revision 1.3 2003/05/26 21:15:20 nilspace +* Fixed the static timevector and static attitude/orbitVec to be cleared on each propagate. +* +* Revision 1.2 2003/05/22 03:00:43 nilspace +* Updated to pass pointers of Orbit & Attitude objects rather than references. +* +* Revision 1.1 2003/05/20 17:56:24 nilspace +* Initial submission. +* +* +******************************************************************************/ diff --git a/src/dynamics/CombinedNumericPropagator.h b/src/dynamics/CombinedNumericPropagator.h new file mode 100644 index 0000000..35ee9c0 --- /dev/null +++ b/src/dynamics/CombinedNumericPropagator.h @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file CombinedNumericPropagator.h +* \brief Interface to the Combined Numeric Propagator class. +* \author $Author: rsharo $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Finish documentation +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_COMBINED_NUMERIC_PROPAGATOR_H__ +#define __OSESSAME_COMBINED_NUMERIC_PROPAGATOR_H__ + +#include "Matrix.h" +#include "Rotation.h" +#include "utils/Integrator.h" +#include "NumericPropagator.h" + +namespace O_SESSAME { + +/*! \brief Propagation of orbit & attitude using a numeric integrator. +* \ingroup PropagatorToolkit +* +* \example testPropagation.cpp +* This example demonstrates how to use a CombinedNumericPropagator to propagate a combined +orbit \& attitude. +*/ +class CombinedNumericPropagator : public NumericPropagator +{ +public: + /*! Default Constructor */ + CombinedNumericPropagator(); + /*! Default Deconstructor */ + virtual ~CombinedNumericPropagator(); + + /*! Propagates the dynamics forward through time + * @param _propTime vector of ssfTime values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + * @param _orbitInitConditions initial conditions of the orbit integration. + * @param _attInitConditions initial conditions of the attitude integration. + */ + virtual void Propagate(const vector &_propTime, const Vector &_orbitInitConditions, const Vector &_attInitConditions); + + void SetOrbitIntegrator(Integrator* _pOrbitIntegrator); + void SetAttitudeIntegrator(Integrator* _pAttitudeIntegrator); + + Integrator* GetOrbitIntegrator() const; + Integrator* GetAttitudeIntegrator() const; + +protected: + /*! \brief Propagate the orbit through a specified time + * @param _propTime vector of values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + * @param _initConditions Vector of initial conditions of the orbit propagation. + * @return Matrix of integrated times and states as returned by the orbit dynamics equation + */ + virtual Matrix PropagateOrbit(const vector &_propTime, const Vector &_initConditions); + + /*! \brief Propagate the attitude through a specified time + * @param _propTime Vector of values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + * @param _initConditions Vector of initial conditions of the attitude propagation. + * @return Matrix of integrated times and states as returned by the attitude dynamics equation + */ + virtual Matrix PropagateAttitude(const vector &_propTime, const Vector &_initConditions); + +private: + /*! \brief Matrix of calculated integration mesh points for the orbit dynamics */ + Matrix m_OrbitStateMeshPoints; + /*! \brief Matrix of calculated integration mesh points for the attitude dynamics */ + Matrix m_AttitudeStateMeshPoints; + + /*! \brief pointer to the integrator used by the numeric propagator for orbit integration. */ + Integrator* m_pOrbitIntegrator; + /*! \brief pointer to the integrator used by the numeric propagator for attitude integration. */ + Integrator* m_pAttitudeIntegrator; +}; +} // close namespace O_SESSAME + +#endif +/***************************************************************************** +* $Log: CombinedNumericPropagator.h,v $ +* Revision 1.4 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.3 2003/06/10 02:24:04 nilspace +* Updated moving of StateConversion functions to Attitude and Orbit. +* +* Revision 1.2 2003/05/22 21:02:28 nilspace +* Updated comments. +* +* Revision 1.1 2003/05/20 17:56:24 nilspace +* Initial submission. +* +* +******************************************************************************/ diff --git a/src/dynamics/Jamfile b/src/dynamics/Jamfile new file mode 100644 index 0000000..0837200 --- /dev/null +++ b/src/dynamics/Jamfile @@ -0,0 +1,30 @@ +########################################### +# Dynamics Jamfile +# +# $Author: simpliciter $ +# $Revision: 1.3 $ +# $Date: 2003/12/08 14:48:27 $ +########################################### + +SubDir OPENSESSAME_ROOT src dynamics ; + +Objects Propagator.cpp NumericPropagator.cpp ; +ObjectHdrs Propagator.cpp NumericPropagator.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)dynamics : Propagator$(SUFOBJ) NumericPropagator$(SUFOBJ) ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)dynamics$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : Propagator.h NumericPropagator.h ; + + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.3 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# ******************************************************************************/ + + + diff --git a/src/dynamics/NumericPropagator.cpp b/src/dynamics/NumericPropagator.cpp new file mode 100644 index 0000000..245658d --- /dev/null +++ b/src/dynamics/NumericPropagator.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file NumericPropagator.cpp +* \brief Implementation of the Numeric Propagator class. +* \author $Author: nilspace $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/05/20 17:55:35 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "NumericPropagator.h" +namespace O_SESSAME { + +NumericPropagator::NumericPropagator() +{ + +} + +NumericPropagator::~NumericPropagator() +{ + +} + +void NumericPropagator::Propagate(const vector &_propTime, const Vector &_orbitInitConditions, const Vector &_attInitConditions) +{ + +} + +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: NumericPropagator.cpp,v $ +* Revision 1.8 2003/05/20 17:55:35 nilspace +* Updated comments, also now use derived CombinedNumericProp. +* +* Revision 1.7 2003/05/13 18:54:04 nilspace +* Fixed comments & various propagate functions. +* +* Revision 1.6 2003/04/30 14:45:35 nilspace +* Set the OrbitStateObject() and AttitudeStateObject() in the Propagate() function. +* +* Revision 1.5 2003/04/29 20:56:03 nilspace +* Updated to work. +* +* Revision 1.4 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.3 2003/04/25 13:43:52 nilspace +* Updated to actually work. Still needs verification. +* +* Revision 1.1 2003/04/08 22:49:56 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/dynamics/NumericPropagator.h b/src/dynamics/NumericPropagator.h new file mode 100644 index 0000000..2258ceb --- /dev/null +++ b/src/dynamics/NumericPropagator.h @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file NumericPropagator.h +* \brief Interface to the Numeric Propagator class. +* \author $Author: rsharo $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Finish documentation +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_NUMERIC_PROPAGATOR_H__ +#define __OSESSAME_NUMERIC_PROPAGATOR_H__ + +#include "Matrix.h" +#include "Rotation.h" +#include "utils/Integrator.h" +#include "Propagator.h" + +namespace O_SESSAME { + +/*! \brief Numeric Propagation of orbit & attitude using a numeric integrator. +* \ingroup PropagatorToolkit +* +* +* \example testDynamics.cpp +*/ +class NumericPropagator : public Propagator +{ +public: + /*! Default Constructor */ + NumericPropagator(); + /*! Default Deconstructor */ + virtual ~NumericPropagator(); + + /*! Propagates the dynamics forward through time + * @param _propTime vector of ssfTime values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + * @param _orbitInitConditions initial conditions of the orbit integration. + * @param _attInitConditions initial conditions of the attitude integration. + */ + virtual void Propagate(const vector &_propTime, const Vector &_orbitInitConditions, const Vector &_attInitConditions); + +protected: + +private: + +}; +} // close namespace O_SESSAME + +#endif +/***************************************************************************** +* $Log: NumericPropagator.h,v $ +* Revision 1.8 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.7 2003/05/22 21:02:16 nilspace +* Updated comments. +* +* Revision 1.6 2003/05/20 17:55:35 nilspace +* Updated comments, also now use derived CombinedNumericProp. +* +* Revision 1.5 2003/05/13 18:54:04 nilspace +* Fixed comments & various propagate functions. +* +* Revision 1.4 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.3 2003/04/25 13:43:52 nilspace +* Updated to actually work. Still needs verification. +* +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:49:56 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/dynamics/Propagator.cpp b/src/dynamics/Propagator.cpp new file mode 100644 index 0000000..0309051 --- /dev/null +++ b/src/dynamics/Propagator.cpp @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Propagator.cpp +* \brief Implementation of the Propagator class. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/06/10 02:24:04 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Propagator.h" + +namespace O_SESSAME { +Propagator::Propagator() : m_pOrbitObject(0), m_pAttitudeObject(0) +{ + m_OrbitStateMeshPoints.ResetHistory(); + m_AttitudeStateMeshPoints.ResetHistory(); +} + +void Propagator::Propagate(const vector &_propTime) +{ +} + +Propagator::~Propagator() +{ +} + +void Propagator::SetAttitudeObject(Attitude *_pAttitudeObject) +{ + m_pAttitudeObject = _pAttitudeObject; +} + +void Propagator::SetOrbitObject(Orbit *_pOrbitObject) +{ + m_pOrbitObject = _pOrbitObject; +} + +Matrix Propagator::PropagateOrbit(const vector &_propTime, const Vector &_initConditions) +{ + return Matrix(0); +} + +Matrix Propagator::PropagateAttitude(const vector &_propTime, const Vector &_initConditions) +{ + return Matrix(0); +} + +} // close namespace O_SESSAME +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Propagator.cpp,v $ +* Revision 1.7 2003/06/10 02:24:04 nilspace +* Updated moving of StateConversion functions to Attitude and Orbit. +* +* Revision 1.6 2003/05/13 18:53:04 nilspace +* Passed in initial conditions to propagate functions. +* +* Revision 1.5 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/25 13:43:52 nilspace +* Updated to actually work. Still needs verification. +* +* Revision 1.3 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.2 2003/04/08 22:50:28 nilspace +* Updated to derive classes based on numeric or analytical nature. +* +* Revision 1.1 2003/03/27 20:24:28 nilspace +* Initial submission +* +******************************************************************************/ diff --git a/src/dynamics/Propagator.h b/src/dynamics/Propagator.h new file mode 100644 index 0000000..5b576c7 --- /dev/null +++ b/src/dynamics/Propagator.h @@ -0,0 +1,168 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Propagator.h +* \brief Interface to the Propagator abstract class. +* \author $Author: rsharo $ +* \version $Revision: 1.11 $ +* \date $Date: 2003/10/18 21:37:27 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Finish documentation +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_PROPAGATOR_H__ +#define __OSESSAME_PROPAGATOR_H__ + +#include "Rotation.h" +#include "utils/Integrator.h" +#include "Orbit.h" +#include "Attitude.h" +#include "AttitudeHistory.h" +#include "OrbitHistory.h" + + +namespace O_SESSAME { +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup PropagatorToolkit Propagator Toolkit +* The propagator toolkit contains all the functionality required to propagate the full dynamics +* of a spacecraft. This can include only attitude or orbit dynamics, combined, or even propagation +* using an external source of states, such as another simulation program or hardware. +* +* \par +* The Propagator class offers an abstract interface to the specific propagation strategies +* that implement each of the examples given above, as well as any further user defined algorithms. +A propagator requires the following parts: + - Orbit object (if propagating with an orbit), including: + - Dynamic equations, the right-hand side, or time derivate equations (odeFunctor) + - A state conversion function that converts the integrated state variables to an + object stored in OrbitHistory. + - An Interpolator in the OrbitHistory. + - Attitude object (if propagating with an attitude), including: + - Dynamic equations, the right-hand side, or time derivate equations (odeFunctor) + - A state conversion function that converts the integrated state variables to an + object stored in AttitudeHistory + - An Interpolator in the AttitudeHistory + - An attitude state propagator + - Use either an Integrator + - Tie in the external source to the AttitudeHistory object (Exporter, Communications) + - An orbit state propagator + - Use either an Integrator + - Tie in the external source to the OrbitHistory object (Exporter, Communications) + - An Environment object + - Environmental force and torque disturbance functions (EnvFunction) + - A CentralBody (EarthCentralBody, MoonCentralBody, etc.) + +An example of a propagator use is included in testPropagation.cpp. + +* +* \par Extension Points: +* The propagation toolkit currently has functionality for independent attitude \& orbit +* propagation, as well as combined propagation using weak coupling, and full coupling. Any new +* propagation schemes should be derived from the appropriate AnalyticPropagator or NumericPropagator +* interface classes as necessary. +*/ + +class Attitude; +class Orbit; + + +/*! \brief Encapsulation of the propagation of the spacecraft dynamics (attitude, orbital, etc.) +* \ingroup PropagatorToolkit +* +* The propagator is used to tie together the various spacecraft dynamics that are desired to be +* propagated. The user has the ability to set the time derivative equations, integrators, parameters, +* etc. as necessary. Furthermore, the Propagator class can be derived for more functionality. +*/ +class Propagator +{ +public: + /*! \brief Default Deconstructor */ + virtual ~Propagator(); + + /*! \brief Propagates the dynamics forward through time + * @param _propTime STL vector of values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + */ + virtual void Propagate(const vector &_propTime); + + /*! \brief Sets the Attitude Representation object to be propagated + * @param _AttitudeObject pointer to the attitude representation + */ + virtual void SetAttitudeObject(Attitude *_pAttitudeObject); + + /*! \brief Sets the Orbit Representation object to be propagated + * @param _OrbitObject pointer to the Orbit representation + */ + virtual void SetOrbitObject(Orbit *_pOrbitObject); + +protected: + /*! \brief Propagate the orbit through a specified time + * @param _propTime vector of values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + * @param _initConditions Vector of initial conditions of the orbit propagation. + * @return Matrix of integrated times and states as returned by the orbit dynamics equation + */ + virtual Matrix PropagateOrbit(const vector &_propTime, const Vector &_initConditions); + + /*! \brief Propagate the attitude through a specified time + * @param _propTime Vector of values specifying beginning, ending times of propagation as well as time step [initialTime, timeStep, finalTime] (s) + * @param _initConditions Vector of initial conditions of the attitude propagation. + * @return Matrix of integrated times and states as returned by the attitude dynamics equation + */ + virtual Matrix PropagateAttitude(const vector &_propTime, const Vector &_initConditions); + +protected: + /*! \brief Default Constructor */ + Propagator(); + + /*! Pointer to the Orbit Representation being propagated */ + Orbit *m_pOrbitObject; + /*! Pointer to the Attitude Representation being propagated */ + Attitude *m_pAttitudeObject; + + /*! Collection of calculated orbit state mesh points */ + OrbitHistory m_OrbitStateMeshPoints; + /*! Collection of calculated attitude state mesh points */ + AttitudeHistory m_AttitudeStateMeshPoints; + +}; +// end of Propagator +} +#endif +/***************************************************************************** +* $Log: Propagator.h,v $ +* Revision 1.11 2003/10/18 21:37:27 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.10 2003/06/10 02:24:04 nilspace +* Updated moving of StateConversion functions to Attitude and Orbit. +* +* Revision 1.9 2003/05/22 15:09:46 nilspace +* Updated documentation. +* +* Revision 1.8 2003/05/20 17:55:35 nilspace +* Updated comments, also now use derived CombinedNumericProp. +* +* Revision 1.7 2003/05/13 18:52:45 nilspace +* Fixed comments. Passed in initial conditions to propagate functions. +* +* Revision 1.6 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.5 2003/04/25 18:23:43 nilspace +* Added implementation of ~Propagator() +* +* Revision 1.4 2003/04/25 13:43:52 nilspace +* Updated to actually work. Still needs verification. +* +* Revision 1.3 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.2 2003/04/08 22:50:28 nilspace +* Updated to derive classes based on numeric or analytical nature. +* +* Revision 1.1 2003/03/27 02:49:20 nilspace +* Initial submission +* +******************************************************************************/ diff --git a/src/dynamics/QuaternionDynamics.h b/src/dynamics/QuaternionDynamics.h new file mode 100644 index 0000000..b9890a0 --- /dev/null +++ b/src/dynamics/QuaternionDynamics.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file QuaternionDynamics.h +* \brief Rigid body dynamic equations of attitude motion in quaternion form. +* \author $Author: nilspace $ +* \version $Revision: 1.3 $ +* \date $Date: 2003/04/23 16:30:58 $ +////////////////////////////////////////////////////////////////////////////////////////////////// +* \todo document the QuaternionDynamics function +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef QUATERNIONDYNAMICS_H +#define QUATERNIONDYNAMICS_H +#include "../rotation/Rotation.h" + +static Vector QuaternionDynamics(const double &_time, const Vector &w_BI, const Matrix &_params) +{ + Matrix MOI(3,3); + MOI = _params(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2)); + Matrix Tmoment(3,1); + Tmoment = ~_params(MatrixIndexBase + 3, _); + Tmoment = (MOI.inverse() * (Tmoment - skew(w_BI) * (MOI * w_BI))); + Vector temp(3); + temp(_) = Tmoment(_,MatrixIndexBase); + return temp; +} + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: QuaternionDynamics.h,v $ +* Revision 1.3 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.2 2003/03/27 02:51:08 nilspace +* Fixed to prevent incorrect vector indexing. +* +* Revision 1.1 2003/03/25 02:29:56 nilspace +* initial submission. Needs to be verified. +* +******************************************************************************/ diff --git a/src/dynamics/dynamics.pro b/src/dynamics/dynamics.pro new file mode 100644 index 0000000..cb896d2 --- /dev/null +++ b/src/dynamics/dynamics.pro @@ -0,0 +1,27 @@ +# +# $Id: dynamics.pro,v 1.3 2003/10/18 21:37:28 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = Propagator.h NumericPropagator.h \ + CombinedNumericPropagator.h +SOURCES = Propagator.cpp NumericPropagator.cpp \ + CombinedNumericPropagator.cpp +TARGET = osessame_dynamics +VERSION = 1.0 +DESTDIR = ../../lib/ +INCLUDEPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment .. +CONFIG = console staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment ../utils diff --git a/src/environment/CVS/Entries b/src/environment/CVS/Entries new file mode 100644 index 0000000..545cf4e --- /dev/null +++ b/src/environment/CVS/Entries @@ -0,0 +1,7 @@ +/Environment.cpp/1.8/Thu Jun 12 18:06:35 2003// +/Environment.h/1.13/Sat Oct 18 21:37:28 2003// +/Jamfile/1.3/Mon Dec 8 14:48:27 2003// +/Makefile/1.9/Sat Oct 18 21:37:28 2003// +/environment.pro/1.5/Sat Oct 18 21:37:28 2003// +D/CentralBody//// +D/Disturbances//// diff --git a/src/environment/CVS/Repository b/src/environment/CVS/Repository new file mode 100644 index 0000000..18e998d --- /dev/null +++ b/src/environment/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/environment diff --git a/src/environment/CVS/Root b/src/environment/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/environment/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/environment/CentralBody/CVS/Entries b/src/environment/CentralBody/CVS/Entries new file mode 100644 index 0000000..6254293 --- /dev/null +++ b/src/environment/CentralBody/CVS/Entries @@ -0,0 +1,5 @@ +/CentralBody.cpp/1.2/Thu Jun 12 17:57:41 2003// +/CentralBody.h/1.4/Sat Oct 18 21:37:28 2003// +/EarthCentralBody.cpp/1.4/Sun Aug 24 20:59:13 2003// +/EarthCentralBody.h/1.2/Mon Jun 9 15:20:39 2003// +D/Models//// diff --git a/src/environment/CentralBody/CVS/Repository b/src/environment/CentralBody/CVS/Repository new file mode 100644 index 0000000..78e70cf --- /dev/null +++ b/src/environment/CentralBody/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/environment/CentralBody diff --git a/src/environment/CentralBody/CVS/Root b/src/environment/CentralBody/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/environment/CentralBody/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/environment/CentralBody/CentralBody.cpp b/src/environment/CentralBody/CentralBody.cpp new file mode 100644 index 0000000..b214769 --- /dev/null +++ b/src/environment/CentralBody/CentralBody.cpp @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file CentralBody.cpp +* \brief Implementation of the CentralBody encapsulation object. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/06/12 17:57:41 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "CentralBody.h" +#include "Models/MagneticModel.h" +namespace O_SESSAME { + +CentralBody::CentralBody() : m_ReferenceCount(0) +{ + +} + +void CentralBody::GetReference() +{ + ++m_ReferenceCount; + return; +} +void CentralBody::ReleaseReference() +{ + --m_ReferenceCount; + if(m_ReferenceCount <= 0) + { /** \todo Check how to verify the number of references & delete the object */ + //delete *this; + } + return; +} + +void CentralBody::SetMagneticModel(MagneticModel* _pNewMagModel) +{ + m_pMagneticFieldModel = _pNewMagModel; + m_pMagneticFieldModel->SetMagFieldCoefficients(m_MagFieldCoeffs); +} + +double CentralBody::GetAvgRotationRate() {return m_AvgRotationRate;} + +double CentralBody::GetRadius() {return m_Radius;} + +CentralBody* CentralBody::operator= (CentralBody*) +{ + GetReference(); return this; +} + +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: CentralBody.cpp,v $ +* Revision 1.2 2003/06/12 17:57:41 nilspace +* Added magnetic models. +* +* Revision 1.1 2003/06/06 17:34:53 nilspace +* Moved to CentralBody directory. +* +* Revision 1.3 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/23 16:29:46 nilspace +* Updated makefile directories. +* +* Revision 1.1 2003/04/08 22:35:11 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/environment/CentralBody/CentralBody.h b/src/environment/CentralBody/CentralBody.h new file mode 100644 index 0000000..7cf7d91 --- /dev/null +++ b/src/environment/CentralBody/CentralBody.h @@ -0,0 +1,132 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file CentralBody.h +* \brief Interface to the CentralBody encapsulation object. +* \author $Author: rsharo $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Add reference counter to ensure deletion when not used anymore. +* \todo finish implementation of the abstract and concrete central bodies. +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __O_SESSAME_CENTRALBODY_H__ +#define __O_SESSAME_CENTRALBODY_H__ + +#include "Rotation.h" +#include "Matrix.h" +#include "OrbitState.h" +#include "utils/Time.h" +#include "Models/MagneticModel.h" + +namespace O_SESSAME { + +/*! \brief Abstract representation of a central body +* \ingroup EnvironmentToolkit +* +* \detail The CentralBody class provides a common interface to the group of central body +* objects (Planet, moon, asteroid, etc.) The central body group stores the pertinent +* parameters that affect the operating environment of a spacecraft. This includes +* the radius, mass, gravity field, atmosphere characteristics (if they is an atm), and +* relationship to other central bodies (such as from the sun, or a moon to planet). +* +*/ +class CentralBody +{ +public: + /*! \brief Default Deconstructor */ + virtual ~CentralBody() {}; + + + // MAGNETIC MODEL + void SetMagneticModel(MagneticModel* _pNewMagModel); + + + // PHYSICAL PARAMETERS + virtual inline double GetAvgRotationRate(); + virtual inline double GetRadius(); + virtual inline double GetGravitationalParameter() { return m_GravitationalParameter; } + + /*! \brief calculate the vector from the central body to another central body */ + Vector GetVector2Body(CentralBody*) const; + + /*! \brief calculate the vector from the central body to a satellite */ + Vector GetVector2Body(const OrbitState& _satOrbitState) const; + + + /*! \brief Returns a pointer to the instance of the central body. */ + CentralBody* operator= (CentralBody*); + + /*! \brief decrease the number of references to the central body pointer */ + void ReleaseReference(); + +protected: + /*! \brief Construct a central body object */ + CentralBody(); + + /*! \brief increase the number of references to the central body pointer */ + void GetReference(); + + + double m_Radius; /**< radius of the central body, [km] */ + double m_Mass; /**< mass of the central body, [kg] */ + double m_GravitationalParameter; /**< gravitational parameter, \f$\mu\f$ [km^3/(solar s)^2] */ + + double m_AtmHeight; + double m_AvgRotationRate; /**< average rotation rate of the central body, [rad/s] */ + Vector m_GravitationalFieldConstants; + + int m_ReferenceCount; + MagneticModel* m_pMagneticFieldModel; + MagneticFieldCoefficients m_MagFieldCoeffs; +}; +} // close namespace O_SESSAME + +/** @defgroup EnvironmentModels Environment Models +* @ingroup EnvironmentToolkit +* Collection of models of the environment of a central body. +* +* Examples include magnetic field, atmosphere, radiation, etc. +*/ + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: CentralBody.h,v $ +* Revision 1.4 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.3 2003/06/12 17:57:41 nilspace +* Added magnetic models. +* +* Revision 1.2 2003/06/09 15:20:39 nilspace +* Changed CentralBody directory. +* +* Revision 1.1 2003/06/06 17:34:53 nilspace +* Moved to CentralBody directory. +* +* Revision 1.7 2003/05/20 17:51:12 nilspace +* Updated comments. +* +* Revision 1.6 2003/05/13 18:59:16 nilspace +* Fixed some comments. +* +* Revision 1.5 2003/05/05 20:45:46 nilspace +* Changed the pass-by-address parameters to pass-by-reference. +* +* Revision 1.4 2003/05/02 16:16:28 nilspace +* Documented the API. +* +* Revision 1.3 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/23 16:29:47 nilspace +* Updated makefile directories. +* +* Revision 1.1 2003/04/08 22:35:11 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/environment/CentralBody/EarthCentralBody.cpp b/src/environment/CentralBody/EarthCentralBody.cpp new file mode 100644 index 0000000..0165419 --- /dev/null +++ b/src/environment/CentralBody/EarthCentralBody.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file EarthCentralBody.cpp +* \brief Implementation of the EarthCentralBody encapsulation object. +* \author $Author: nilspace $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/08/24 20:59:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "EarthCentralBody.h" +namespace O_SESSAME { + + +EarthCentralBody::EarthCentralBody() +{ + m_Radius = 6378.140;// * _KM; + m_Mass = 5.9742 * pow(10,24);// * _KG; + m_GravitationalParameter = 398600.4415;// * km^3/(solar s)^2; + + m_AvgRotationRate = 7.2921152 * pow(10, -5); // rad/s + + // Set the coefficients of the magnetic field corresponding the IGRF2000 + m_MagFieldCoeffs.modelEpoch.SetEpoch(2000, 1, 1, 0, 0, 0); + m_MagFieldCoeffs.H0 = 30115; // nT + m_MagFieldCoeffs.DipoleCoelevation = Deg2Rad(196.54); + m_MagFieldCoeffs.DipoleEastLongitude= Deg2Rad(108.43); + m_MagFieldCoeffs.CBAvgRotationRate = m_AvgRotationRate; + m_MagFieldCoeffs.CBRadius = m_Radius; +} +/* +void EarthCentralBody::CalcWc(const double &_altitude) +{ + m_wc = ::sqrt(GRAVITATIONAL_CONSTANT * m_Mass / pow(_altitude+m_Radius, 3)); + return; +}*/ +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: EarthCentralBody.cpp,v $ +* Revision 1.4 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.3 2003/06/12 18:01:09 nilspace +* Added magnetic parameters. +* +* Revision 1.2 2003/06/09 15:20:39 nilspace +* Changed CentralBody directory. +* +* Revision 1.1 2003/06/06 17:34:53 nilspace +* Moved to CentralBody directory. +* +* Revision 1.2 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.1 2003/04/08 22:36:51 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/CentralBody/EarthCentralBody.h b/src/environment/CentralBody/EarthCentralBody.h new file mode 100644 index 0000000..f6c3fd8 --- /dev/null +++ b/src/environment/CentralBody/EarthCentralBody.h @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file EarthCentralBody.h +* \brief Interface to the EarthCentralBody object. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/06/09 15:20:39 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __EARTH_CENTRALBODY_H__ +#define __EARTH_CENTRALBODY_H__ +#include "math.h" +#include "Rotation.h" +//#include "Units.h" +#include "CentralBody.h" +#define PI 3.141592 + +namespace O_SESSAME { + +/*! Earth Radius [/f$m^3/kg-s^2/f$] */ +const double GRAVITATIONAL_CONSTANT = 6.669 * pow(10.0,-11.0); +/*! Earth Radius [-] */ +const double deg2rad = (float)PI / 180.0; + +class EarthCentralBody : public CentralBody +{ +public: + EarthCentralBody(); + +private: +}; +} // close namespace O_SESSAME + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: EarthCentralBody.h,v $ +* Revision 1.2 2003/06/09 15:20:39 nilspace +* Changed CentralBody directory. +* +* Revision 1.1 2003/06/06 17:34:53 nilspace +* Moved to CentralBody directory. +* +* Revision 1.2 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.1 2003/04/08 22:36:51 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/CentralBody/Models/CVS/Entries b/src/environment/CentralBody/Models/CVS/Entries new file mode 100644 index 0000000..7526ac5 --- /dev/null +++ b/src/environment/CentralBody/Models/CVS/Entries @@ -0,0 +1,4 @@ +/MagneticModel.h/1.4/Sat Oct 18 21:37:28 2003// +/TiltedDipoleMagneticModel.cpp/1.2/Thu Jun 12 18:00:31 2003// +/TiltedDipoleMagneticModel.h/1.2/Thu Jun 12 18:00:31 2003// +D diff --git a/src/environment/CentralBody/Models/CVS/Repository b/src/environment/CentralBody/Models/CVS/Repository new file mode 100644 index 0000000..ec0db75 --- /dev/null +++ b/src/environment/CentralBody/Models/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/environment/CentralBody/Models diff --git a/src/environment/CentralBody/Models/CVS/Root b/src/environment/CentralBody/Models/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/environment/CentralBody/Models/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/environment/CentralBody/Models/MagneticModel.h b/src/environment/CentralBody/Models/MagneticModel.h new file mode 100644 index 0000000..d32710a --- /dev/null +++ b/src/environment/CentralBody/Models/MagneticModel.h @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file MagneticModel.h +* \brief Class for describing the magnetic model of a central body. +* \author $Author: rsharo $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_MAGNETIC_MODEL_H__ +#define __OSESSAME_MAGNETIC_MODEL_H__ + +#include "Matrix.h" +#include "utils/Time.h" + +namespace O_SESSAME { + + /** @brief Structure to hold typical magnetic model coefficients. */ + typedef struct { + ssfTime modelEpoch; /**< time of model epoch, set in ssfTime::Epoch */ + double H0; /**< coefficient of Field strength, [nT] */ + double DipoleCoelevation; /**< coelevation of the dipole at epoch, [rad] */ + double DipoleEastLongitude; /**< east longitude of the dipole at epoch, [rad] */ + double CBAvgRotationRate; /**< average rotation rate of central body, [rad/s] */ + double CBRadius; /**< radius of the central body, [km] */ + } MagneticFieldCoefficients; + +/** @brief The MagneticModel class encapsulates a magnetic model of a central body. +* @ingroup EnvironmentModels +*/ +class MagneticModel +{ +public: + virtual ~MagneticModel() {} + + virtual Vector GetMagneticField(const ssfTime& _currentTime, const Vector& _PositionVector) = 0; + virtual void SetMagFieldCoefficients(const MagneticFieldCoefficients& _newMagFieldCoeffs) {m_MagFieldCoeffs = _newMagFieldCoeffs;} + +protected: + MagneticModel() {} + + MagneticFieldCoefficients m_MagFieldCoeffs; + +private: + +}; +} +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: MagneticModel.h,v $ +* Revision 1.4 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.3 2003/06/12 18:00:31 nilspace +* Fixed references to CentralBody. +* +* Revision 1.2 2003/06/10 14:45:43 nilspace +* Changed include from Vector.h to Matrix.h +* +* Revision 1.1 2003/06/10 14:26:50 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/CentralBody/Models/TiltedDipoleMagneticModel.cpp b/src/environment/CentralBody/Models/TiltedDipoleMagneticModel.cpp new file mode 100644 index 0000000..325289c --- /dev/null +++ b/src/environment/CentralBody/Models/TiltedDipoleMagneticModel.cpp @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file TiltedDipoleMagneticModel.cpp +* \brief Algorithm for determining the magnetic field of a central body using a titled dipole mognetic model. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/06/12 18:00:31 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "TiltedDipoleMagneticModel.h" + +namespace O_SESSAME { + +/*! \brief Calculates the local magnetic field about a central body used a tilted dipole model. +* +*/ +Vector TiltedDipoleMagneticModel::GetMagneticField(const ssfTime& _currentTime, const Vector& _PositionVector) +{ + m_MagFieldCoeffs.modelEpoch.Set(_currentTime.GetSeconds()); + double alpha_m = m_MagFieldCoeffs.modelEpoch.GetEpochGreenwichMeanSiderealTime() + + m_MagFieldCoeffs.CBAvgRotationRate * m_MagFieldCoeffs.modelEpoch.SecondsSinceEpoch() + + m_MagFieldCoeffs.DipoleEastLongitude; + + static Vector DipoleDirection(3); + DipoleDirection(1) = sin(m_MagFieldCoeffs.DipoleCoelevation) * cos(alpha_m); + DipoleDirection(2) = sin(m_MagFieldCoeffs.DipoleCoelevation) * sin(alpha_m); + DipoleDirection(3) = cos(m_MagFieldCoeffs.DipoleCoelevation); + + return pow(m_MagFieldCoeffs.CBRadius,3) * m_MagFieldCoeffs.H0 + / pow(norm2(_PositionVector),3) + * (3 * (~DipoleDirection * _PositionVector) * _PositionVector - DipoleDirection); + +} +} + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: TiltedDipoleMagneticModel.cpp,v $ +* Revision 1.2 2003/06/12 18:00:31 nilspace +* Fixed references to CentralBody. +* +* Revision 1.1 2003/06/10 14:26:50 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/CentralBody/Models/TiltedDipoleMagneticModel.h b/src/environment/CentralBody/Models/TiltedDipoleMagneticModel.h new file mode 100644 index 0000000..13ccad6 --- /dev/null +++ b/src/environment/CentralBody/Models/TiltedDipoleMagneticModel.h @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file TiltedDipoleMagenticModel.h +* \brief Magnetic field model using a tilted dipole. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/06/12 18:00:31 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_TILTED_DIPOLE_MAGNETIC_MODEL_H__ +#define __OSESSAME_TILTED_DIPOLE_MAGNETIC_MODEL_H__ + +#include "MagneticModel.h" + +namespace O_SESSAME { + +/** @brief Define the model of a magnetic field using a tilted dipole model. +* @ingroup EnvironmentModels +*/ +class TiltedDipoleMagneticModel : public MagneticModel +{ +public: + TiltedDipoleMagneticModel() {}; + virtual ~TiltedDipoleMagneticModel() {}; + + virtual Vector GetMagneticField(const ssfTime& _currentTime, const Vector& _PositionVector); + +protected: + +private: + +}; +} +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: TiltedDipoleMagneticModel.h,v $ +* Revision 1.2 2003/06/12 18:00:31 nilspace +* Fixed references to CentralBody. +* +* Revision 1.1 2003/06/10 14:26:50 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/Disturbances/CVS/Entries b/src/environment/Disturbances/CVS/Entries new file mode 100644 index 0000000..ca3f42d --- /dev/null +++ b/src/environment/Disturbances/CVS/Entries @@ -0,0 +1,4 @@ +/GravityFunctions.h/1.4/Sat Oct 18 21:37:28 2003// +/SolarDisturbances.h/1.3/Sat Oct 18 21:37:28 2003// +/ThirdBodyDisturbances.h/1.2/Sat Oct 18 21:37:28 2003// +D diff --git a/src/environment/Disturbances/CVS/Repository b/src/environment/Disturbances/CVS/Repository new file mode 100644 index 0000000..d7ff31d --- /dev/null +++ b/src/environment/Disturbances/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/environment/Disturbances diff --git a/src/environment/Disturbances/CVS/Root b/src/environment/Disturbances/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/environment/Disturbances/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/environment/Disturbances/GravityFunctions.h b/src/environment/Disturbances/GravityFunctions.h new file mode 100644 index 0000000..dac3809 --- /dev/null +++ b/src/environment/Disturbances/GravityFunctions.h @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file GravityFunctions.h +* \brief Gravity force function models. +* \author $Author: rsharo $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_GRAVITYFUNCTIONS_H__ +#define __OSESSAME_GRAVITYFUNCTIONS_H__ +#include "matrix/Matrix.h" +#include "utils/Time.h" +#include "OrbitState.h" +#include "Attitude.h" +#include "Environment.h" +#include +using namespace std; +using namespace O_SESSAME; + +/*! \brief Gravity force function modeling two-body gravity. +* @ingroup EnvironmentForceFunctions +* +* +Newton formulated the simplified two-body equation, or Law of Universal Gravitation. This formulation is a simplified model because it only accounts for two bodies: the central body, and the spacecraft. In general it can be applied to any two massive bodies which have a gravitational attraction with the following assumptions: +-# The bodies are spherically symmetric. +-# There are no external or internal forces acting on the system other than the gravitational forces which act along the line joining the centers of the two bodies. + +\image html images\TwoBody.jpg +\image latex images\TwoBody.pdf "Two body gravity diagram" +\par +Newton's Law of Universal Gravitation states that the force of gravity between two bodies is proportional to the product of their masses and inversely proportional to the square of the distance between them: +\f[ +{\bf F}_{g} = - \frac{GMm}{r^{2}}\frac{{\bf r}}{r} +\f] +where \f${\bf F}_{g}\f$ is the force of gravity acting on mass \f$M\f$ and \f$m\f$, and the vector between the two masses is \f${\bf r}={\bf r}_{M}-{\bf r}_{m}\f$. The parameter \f$G\f$ is the universal contant, which is usually measured by observing the quantity \f$Gm_{\oplus}\f$, since the mass of the earth is large and more easily measured. This gravitational parameter, \f$\mu\f$ has a modern (most recent, accurate) value of \f$3.986\,004\,415\times 10^{5} \frac{km^{3}}{s^{2}}\f$. It is important to note that the vector \f${\bf r}\f$ is measured with respect to inertial axes. + +* @param _currentTime current simulation time +* @param _currentOrbitState current orbit state, including representation and reference frame +* @param _currentAttitudeState current attitude state, including rotation and reference frame +* @param _parameterList EnvFuncParamaterType parameter list for external variables = [\f$\mu\f$], gravitational parameter [km^3/(solar s)^2] +* @return This force functions returns a 3-element vector of forces (x,y,z) due to gravity using a +* two-body simplified force model. +*/ +inline Vector GravityForceFunction(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) +{ + static Vector Forces(3); + static Vector Position(3); + Position(_) = _currentOrbitState.GetState()(_(VectorIndexBase,VectorIndexBase+2)); + Forces = - *(reinterpret_cast(_parameterList[0])) / pow(norm2(Position),3) * Position; + return Forces; +} + +/*! \brief Gravity gradient torque function modeling two-body gravity. +* @ingroup EnvironmentTorqueFunctions +* +The spacecraft body is subject to a non-uniform gravity field which can cause external torques about the body +center. This non-uniformity is due to the inverse-square relation of the force field and the distance from the +mass center, as well as a non-spherical, non-homogenous central body (such as the Earth, but especially true +for asteroid or irregularly shaped central bodies). + +The gravity gradient torque about the body principal axes is: +\f[ +{\bf T}_{gg} = 3\omega _c ^2 {\bf o_3} ^{\times} {\bf{I}}{\bf o_3} +\f] +where \f$\omega_c = 3\frac{\mu}{r^{3}}\f$ and \f$\mathbf{o_{3}}\f$ is the +\f$3^{rd}\f$ column of the body-orbital rotation. + +For enhanced accuracy, a better model would include a higher order gravity field that is dependent on the +spacecraft's position and the central body's orientation. Furthermore, it is useful to analyze the spacecraft's +moment of inertia matrix to evaluate its stability due to the gravity gradient disturbance torque. + +* @param _currentTime current simulation time +* @param _currentOrbitState current orbit state, including representation and reference frame +* @param _currentAttitudeState current attitude state, including rotation and reference frame +* @param _parameterList EnvFuncParamaterType parameter list for external variables = [\f$MOI; \mu\f$], Moments of Inertia, gravitational parameter +* @return This force functions returns a 3-element vector of torques (Tx,Ty,Tz) due to gravity gradient using a +* two-body simplified force model. +*/ +inline Vector GravityGradientTorque(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) +{ + static Matrix MOI(3,3); MOI = *(reinterpret_cast(_parameterList[0])); + static Vector o3(3); o3 = (_currentAttitudeState.GetRotation2Orbital(_currentOrbitState)).GetDCM()(_,3); + static Vector Position(3); Position = (_currentOrbitState.GetStateRepresentation()->GetPositionVelocity())(_(1,3)); + return 3 * *(reinterpret_cast(_parameterList[1]))/(pow(norm2(Position),3)) * skew(o3) * MOI * o3; +} + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: GravityFunctions.h,v $ +* Revision 1.4 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.3 2003/06/12 23:06:21 nilspace +* Fixed torque function. +* +* Revision 1.2 2003/06/12 21:26:50 nilspace +* Replaced minus sign in Forces calculation. +* +* Revision 1.1 2003/06/12 17:58:40 nilspace +* Initial Submission. +* +* Revision 1.6 2003/05/22 21:03:26 nilspace +* Fixed to run faster with static variables. +* +* Revision 1.5 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.4 2003/05/13 18:49:41 nilspace +* Fixed to get the StateObjects. +* +* Revision 1.3 2003/05/10 00:43:13 nilspace +* Updated the includes for Orbit.h and Attitude.h +* +* Revision 1.2 2003/04/22 20:25:44 simpliciter +* Updated LaTeX formulas for \ddot{r} and \dot{state vector} for +* proper display. +* +* Revision 1.1 2003/04/08 22:48:29 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/Disturbances/SolarDisturbances.h b/src/environment/Disturbances/SolarDisturbances.h new file mode 100644 index 0000000..6528594 --- /dev/null +++ b/src/environment/Disturbances/SolarDisturbances.h @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file SolarDisturbances.h +* \brief Solar disturbance function models. +* \author $Author: rsharo $ +* \version $Revision: 1.3 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_SOLAR_DISTURBANCES_H__ +#define __OSESSAME_SOLAR_DISTURBANCES_H__ +#include "matrix/Matrix.h" +#include "utils/Time.h" +#include "OrbitState.h" +#include "Attitude.h" +#include "Environment.h" +#include +using namespace std; +using namespace O_SESSAME; + +/*! \brief Solar radiation pressure environmental disturbance force function. +* @ingroup EnvironmentForceFunctions +* +Another non-conservative disturbance force, like atmospheric drag, is due to the fact that light photons can +impart a force on an absorbing or reflecting body. The force of these photons is usually very low, but can vary +largely between eclipse, based on the body, and during solar storms. The solar-radiation pressure is even the +basis for such spacecraft propulsion designs as solar sails, and so should be used for accurate models. + +The solar pressure, \f$p_{SR}\f$, or change in momentum, is the main parameter in determing the force of the +solar-radiation pressure. For the Earth, this has a nominal value of \f$4.51 \times 10^{-6}\frac{N}{m^{2}}\f$, +where more precise values can be calculated depending on the time of year, as well as position from the Sun. The +effect of solar-radiation pressure also varies due to the reflectivity, \f$c_{R}\f$, of the spacecraft, where 0.0 +indicates no effect, 1.0 is a completely absorbing body, and 2.0 is an absorbing and reflecting body. + +The combined force of the solar radiation pressure is found to be: +\f[ + \vec{a}_{radiation} = -\frac{p_{SR}c_{R}A_{S}}{m}\frac{\vec{\bf{r}}_{\odot sat}}{\left|\vec{\bf{r}}_{\odot sat}\right|} +\f] +where \f$\vec{\bf{r}}_{\odot sat}\f$ is the distance from the satellite to the sun (or light-emitting body), and \f$A_{S}\f$ is the spacecraft's exposed area to the sun. This value of area is very important for calculating the disturbance difference as the spacecraft passes from full sunlight, into eclipse, or when being shadowed by another body (moon or another spacecraft). + +Using basic geometry, it can be shown that simple conditions for determining if a satellite is in sunlight are\cite{Vallado:97}: +\f[ + \tau_{min} = \frac{\left|\vec{\bf{r}}_{sat}\right|^{2}-\vec{\bf{r}}_{sat}\cdot\vec{\bf{r}}_{\odot}}{\left|\vec{\bf{r}}_{sat}\right|^{2} + \left|\vec{\bf{r}}_{\oplus}\right|^{2}-2\vec{\bf{r}}_{sat}\cdot\vec{\bf{r}}_{\odot}} +\f] +\f[ + \mbox{Sunlight if } \tau_{min} < 0\mbox{ or }\tau_{min}>1 +\f] +\f[ + \mbox{ or } \left|\vec{c}\left(\tau_{min}\right)\right|^{2} = \left(1-\tau_{min}\right)\left|\vec{\bf{r}}_{sat}\right|^{2}+\left(\vec{\bf{r}}_{sat}\cdot\vec{\bf{r}}_{\oplus}\right)\tau_{min}\geq 1.0 +\f] + +* \todo Add checking for eclipse. +* @param _currentTime current simulation time +* @param _currentOrbitState current orbit state, including representation and reference frame +* @param _currentAttitudeState current attitude state, including rotation and reference frame +* @param _parameterList EnvFuncParamaterType parameter list for external variables + \par + \f[\begin{bmatrix} + \left[r_{\odot sat_{x}}, r_{\odot sat_{y}}, r_{\odot sat_{z}}\right]^{T} \\ + m, mass (kg) \\ p_{SR}, solar pressure (N/m^2) \\ c_{R}, reflectivity \\ A, Area (m^2) + \end{bmatrix}\f] + \f$r_{\odot sat}\f$ = distance from satellite to the sun (m) +* @return This force functions returns a 3-element vector of forces (x,y,z) due to solar radiation pressure using a +* simplified force model. +*/ +Vector SolarRadiationPressureForceFunction(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) +{ + static Vector Forces(3); + static Vector SunVector(3); + static double p_SR, c_R, m, A_S; + SunSatVector(_) = *(reinterpret_cast(_parameterList[0])); + m = *(reinterpret_cast(_parameterList[1])); + p_SR = *(reinterpret_cast(_parameterList[2])); + c_R = *(reinterpret_cast(_parameterList[3])); + A_R = *(reinterpret_cast(_parameterList[4])); + + Forces = -p_SR * c_R * A_S / m * SunSatVector / norm2(SunSatVector); + return Forces; +} + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: SolarDisturbances.h,v $ +* Revision 1.3 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.2 2003/06/12 21:51:54 nilspace +* Removed & alignment characters from comments. +* +* Revision 1.1 2003/06/12 17:58:42 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/Disturbances/ThirdBodyDisturbances.h b/src/environment/Disturbances/ThirdBodyDisturbances.h new file mode 100644 index 0000000..a99d247 --- /dev/null +++ b/src/environment/Disturbances/ThirdBodyDisturbances.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file ThirdBodyDisturbances.h +* \brief Environmental disturbances due to Third Bodies. +* \author $Author: rsharo $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_THIRDBODY_PERTUBATIONS_H__ +#define __OSESSAME_THIRDBODY_PERTUBATIONS_H__ +#include "matrix/Matrix.h" +#include "utils/Time.h" +#include "OrbitState.h" +#include "Attitude.h" +#include "Environment.h" +#include +using namespace std; +using namespace O_SESSAME; + +/*! \brief The third body force disturbance due to gravity. +* @ingroup EnvironmentForceFunctions +* +* +* @param _currentTime current simulation time +* @param _currentOrbitState current orbit state, including representation and reference frame +* @param _currentAttitudeState current attitude state, including rotation and reference frame +* @param _parameterList EnvFuncParamaterType parameter list for external variables, [CentralBody* orbiting central body, CentralBody* third-body] +* @return This force functions returns a 3-element vector of forces (x,y,z) due to gravity using a +* two-body simplified force model. +*/ +Vector ThirdBodyForceDisturbance(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) +{ + static Vector Forces(3); + static Vector Position(3); + static CentralBody* pOrbCB, pThirdBody; + pOrbCB = reinterpret_cast(_parameterList[0]); + pThirdBody = reinterpret_cast(_parameterList[1]); + + static double massThirdBody = pThirdBody->GetMass(); + static Vector vectorOrbCB2ThirdBody = pOrbCB->GetVector2Body(pThirdBody); + static Vector vectorThirdBody2Satellite(3); + vectorSat2ThirdBody = - pThirdBody->GetVector2Body(_currentOrbitState); // negative to "switch the head" around + static double B = norm2(vectorOrbCB2ThirdBody) / norm2(vectorSat2ThirdBody) - 1; + static double beta = pow(1+B, 3); + + Position(_) = _currentOrbitState.GetState()(_(VectorIndexBase,VectorIndexBase+2)); + Forces = - c_GravitationalConstant * massThirdBody / pow(vectorOrbCB2ThirdBody, 3) * (Position(_) - beta * vectorSat2ThirdBody); + return Forces; +} + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: ThirdBodyDisturbances.h,v $ +* Revision 1.2 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.1 2003/06/12 17:58:42 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/Environment.cpp b/src/environment/Environment.cpp new file mode 100644 index 0000000..9949774 --- /dev/null +++ b/src/environment/Environment.cpp @@ -0,0 +1,260 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Environment.cpp +* \brief Implementation of the Environment encapsulation object. +* \author $Author: nilspace $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/06/12 18:06:35 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Environment.h" +#include "CentralBody/CentralBody.h" +namespace O_SESSAME { + +/*! \brief Create an instance of Environment */ +Environment::Environment() : m_CalculatedForces(3), + m_CalculatedTorques(3), + m_ForcesFunctor(const_cast(this), &Environment::GetForces), + m_TorquesFunctor(const_cast(this), &Environment::GetTorques) +{ + m_pCB = NULL; +} + +/*! \brief Default Deconstructor */ +Environment::~Environment() +{ + if(m_pCB) + m_pCB->ReleaseReference(); +} + + /*! \brief Evaluate the current disturbance torques given a state. + * @param _currentTime current time to evaluate at. + * @param _currentOrbitState current orbital state. + * @param _currentAttitudeState current attitude state. + * @return 3-element vector of disturbance torques in the body frame (N). + */ +Vector Environment::GetTorques(const ssfTime& _currentTime, const OrbitState& _currentOrbitState, const AttitudeState& _currentAttitudeState) +{ + m_CalculatedTorques.setToValue(0); + m_funcIterator = m_TorqueFunctions.begin(); + while (m_funcIterator != m_TorqueFunctions.end()) + { + m_CalculatedTorques += (*m_funcIterator).Evaluate(_currentTime, _currentOrbitState, _currentAttitudeState); + ++m_funcIterator; + } + return m_CalculatedTorques; +} + + /*! \brief Evaluate the current disturbance forces given a state. + * @param _currentTime current time to evaluate at. + * @param _currentOrbitState current orbital state. + * @param _currentAttitudeState current attitude state. + * @return 3-element vector of disturbance forces in the body frame (N). + */ +Vector Environment::GetForces(const ssfTime& _currentTime, const OrbitState& _currentOrbitState, const AttitudeState& _currentAttitudeState) +{ + m_CalculatedForces.setToValue(0); + m_funcIterator = m_ForceFunctions.begin(); + while (m_funcIterator != m_ForceFunctions.end()) + { + m_CalculatedForces += (*m_funcIterator).Evaluate(_currentTime, _currentOrbitState, _currentAttitudeState); + ++m_funcIterator; + } + return m_CalculatedForces; +} + + /*! \brief Set the pointer to the central body to use for modeling the environment. + * @param _pCB pointer to the CentralBody object. + */ +void Environment::SetCentralBody(CentralBody *_pCB) +{ + m_pCB = _pCB; + return; +} + + /*! \brief Get the pointer to the environment's central body. + * @return pointer to the CentralBody object. + */ +const CentralBody* Environment::GetCentralBody() const +{ + return m_pCB; +} + + /*! \brief Add a force disturbance function to the list of force functions + * @param _forceFunc Pointer to a force function that matches the EnvFunction prototype. + */ +void Environment::AddForceFunction(const EnvFunction &_forceFunc) +{ + // iterate through the set of Force Functions to prevent duplication. + /** \todo Check to prevent overlapping force functions *//* + m_funcIterator = m_ForceFunctions.begin(); + while (m_funcIterator != m_ForceFunctions.end()) + { + if(*m_funcIterator == _forceFunc) + return; + }*/ + m_ForceFunctions.push_back(_forceFunc); + return; +} + /*! \brief Add a torque disturbance function to the list of force functions + * @param _forceFunc Pointer to a torque function that matches the EnvFunction prototype. + */ +void Environment::AddTorqueFunction(const EnvFunction &_torqueFunc) +{ + // iterate through the set of Torque Functions to prevent duplication. + /** \todo Check to prevent overlapping torque functions *//* + m_funcIterator = m_TorqueFunctions.begin(); + while (m_funcIterator != m_TorqueFunctions.end()) + { + if(*m_funcIterator == _torqueFunc) + return; + }*/ + m_TorqueFunctions.push_back(_torqueFunc); + return; +} + + /*! \brief Get the reference to the Environment::GetForces() function. + * @return reference to the environment's GetForces() function. + */ +const Functor& Environment::GetForceFunction() const +{ + return m_ForcesFunctor; +} + + /*! \brief Get the reference to the Environment::GetTorques() function. + * @return reference to environment's GetTorques() function. + */ +const Functor& Environment::GetTorqueFunction() const +{ + return m_TorquesFunctor; +} +////////////////////////////////////////////////////// +// EnvFunction Member Functions +////////////////////////////////////////////////////// + /*! \brief Create a disturbance function. + * + * Example: EnvFunction DragForce(&myDisturbanceFunction); + * @param _EnvFuncPtr pointer to an environmental disturbance function. + */ +EnvFunction::EnvFunction(pt2EnvFunc _EnvFuncPtr) : m_NumParameters(0) , m_EnvFuncParameters(m_NumParameters) +{ + m_EnvFuncPtr = _EnvFuncPtr; +} + /*! \brief Create a disturbance function with a set number of parameters. + * + * Example: EnvFunction DragForce(&myDisturbanceFunction, 2); + * @param _EnvFuncPtr pointer to an environmental disturbance function. + * @param _numParameters number of parameters that are passed to the disturbance function. + */ +EnvFunction::EnvFunction(pt2EnvFunc _EnvFuncPtr, const int &_numParameters) : m_NumParameters(_numParameters) , m_EnvFuncParameters(m_NumParameters) +{ + m_EnvFuncPtr = _EnvFuncPtr; +} + /*! \brief Evaluate the disturbance function at a specific state. + * Used to calculate the actual force or torque disturbance given the time, orbit state and attitude state. + * @param _currentTime current time to evaluate at. + * @param _currentOrbitState current orbital state. + * @param _currentAttitudeState current attitude state. + * @return 3-element vector of forces (N) or torques (Nm) from the disturbance at the specified state. + */ +Vector EnvFunction::Evaluate(const ssfTime& _currentTime, const OrbitState& _currentOrbitState, const AttitudeState& _currentAttitudeState) +{ + return m_EnvFuncPtr(_currentTime, _currentOrbitState, _currentAttitudeState, m_EnvFuncParameters); +} + + /*! \brief Add a parameter to the parameter list. + * + * The parameter is inserted in the specified position in the list of parameters, pushing any other parameters back. The list of parameters is passed into the disturbance function (ie mass, ballistic coefficient, magnetic dipole) + *

Example:

MagneticForce.AddParameter(reinterpret_cast(Spacecraft.GetDipole(), 2); where the GetDipole() function returns by reference. + *

If a parameter position is given that is beyond the last position, the parameter will be put in the last position, the intermediate parameters will be filled with empty parameters. + * \warning Make sure the variable that you are passing in as a parameter will stay in scope during the disturbance function calls. + * @param _parameter pointer to the data where the pertinent variable is stored. + * @param _paramNumber Position in the list of parameters. If none is specified, the parameter is put at the end. + */ +void EnvFunction::AddParameter(void* _parameter, int _paramNumber) +{ + if (_paramNumber > m_NumParameters) + { + // Calculate the number of parameters "missing" to be temporarily filled + int delta = _paramNumber - m_NumParameters; + if(delta > 1) + { + for(int ii = 1; ii < delta; ++ii) + { + m_EnvFuncParameters.push_back(0); + } + } + m_EnvFuncParameters.push_back(_parameter); + } + else + m_EnvFuncParameters.insert(m_EnvFuncParameters.begin() + _paramNumber - 1, _parameter); + + m_NumParameters = _paramNumber; + +} + + /*! \brief Changes what a parameter in the list points to. + * + * @param _parameter pointer to the data where the pertinent variable is stored. + * @param _paramNumber Position in the list of parameters. If none is specified, the parameter is put at the end. + */ +void EnvFunction::ChangeParameter(void* _parameter, int _paramNumber) +{ + RemoveParameter(_paramNumber); + AddParameter(_parameter, _paramNumber); +} + + /*! \brief Removes a parameter from the parameter list. + * + * the parameters following the removed parameters will all move down one step to "fill the spot". + *

If no position is specified, the last parameter in the list is removed. + *

If a position is given that is greater than the number of parameters, nothing happens to the list. + *

Example:

ParameterList = [Area, Dipole, Mass], RemoveParameter(2); ParameterList = [Area, Mass] + * @param _paramNumber Position of the parameter to be removed. If none is specified, remove the last parameter in the list. + */ +void EnvFunction::RemoveParameter(int _paramNumber) +{ + if(_paramNumber <= m_NumParameters) + m_EnvFuncParameters.erase(m_EnvFuncParameters.begin()+_paramNumber); + else if(_paramNumber == -1) + m_EnvFuncParameters.pop_back(); + else + return; + + --m_NumParameters; +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Environment.cpp,v $ +* Revision 1.8 2003/06/12 18:06:35 nilspace +* . +* +* Revision 1.7 2003/06/10 15:58:52 nilspace +* GetTorques now incrementes the function iterator. +* +* Revision 1.6 2003/05/22 03:42:32 nilspace +* Moved documentation to the implementation file. +* +* Revision 1.5 2003/05/13 18:59:16 nilspace +* Fixed some comments. +* +* Revision 1.4 2003/05/05 20:45:46 nilspace +* Changed the pass-by-address parameters to pass-by-reference. +* +* Revision 1.3 2003/05/02 02:16:29 nilspace +* Documented the API. +* Added a GetTorquesFunction(). +* +* Revision 1.2 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.1 2003/04/08 22:37:22 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/Environment.h b/src/environment/Environment.h new file mode 100644 index 0000000..e497ecd --- /dev/null +++ b/src/environment/Environment.h @@ -0,0 +1,272 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Environment.h +* \brief Interface to the Environment encapsulation object. +* \author $Author: rsharo $ +* \version $Revision: 1.13 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Add name strings and outputting of "turned-on" disturbances +* \todo Add reference counter to ensure deletion when not used anymore. +* \todo Add CreateIterator() function +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __ENVIRONMENT_H__ +#define __ENVIRONMENT_H__ + +#include "Rotation.h" +#include "utils/Integrator.h" +#include "Matrix.h" +#include "utils/Time.h" +#include +#include + +using namespace std; + +namespace O_SESSAME { +class CentralBody; + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup EnvironmentToolkit Environment Toolkit +* The Environment Toolkit is the collection of classes and functions that assist in modeling a +* spacecraft's external environment. This includes the central bodies, disturbance forces and +* disturbance torques. +* +* \par Extension Points: +* The current toolkit provides functionality for the main planets of the solar system as +* central bodies. There are other central bodies such as moons, asteroids, comets, or stars that +* could be added by deriving from the CentralBody interface class. Furthermore, only a couple of +* the primary disturbance torque and force functions have been implemented. There are numerous +* models of varying complexity that could be added. The only stipulation is that these new disturbance +* functions match the parameterization specified by pt2EnvFunc. +*/ + +/*! specification of the parameter list type to be used for environmental function pointers */ +typedef vector EnvFuncParamaterType; +/*! defines a pointer to a Environmental disturbance calculating function */ +typedef Vector(*pt2EnvFunc)(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList); + +/*! \brief Encapsulation of an environmental disturbance function. +* \ingroup EnvironmentToolkit +* +* An EnvFunction is used to store a function pointer and the list of parameters +* that are used in evaluating an environmental disturbance function. The +* function can either be a force or torque disturbance. Examples include:

+* +* \par (force) Gravity, aerodynamic drag, solar radiation pressure +* \par (torque) Gravity gradient, magnetic, aerodynamic, fuel slosh

+* +* \oar The parameters are the constants (such as Ballistic coefficient, +* magnetic dipole, cross-sectional area), in the appropriate function +* order, and can be set or removed individually. Furthermore, because +* they are actually pointers to data, once the pointer is set, the data +* can still change (for example the mass of the spacecraft) without +* having to alter the EnvFunction parameter list.

+* +* \par Usage: +* To use the EnvFunction class, the user first creates a disturbance +* function that matches the prototype of pt2EnvFunc, which takes the +* current time, orbit state, attitude state, and an STL vector +* of pointers to the parameters. They then must create an instance of +* an EnvFunction with a pointer to the function: +* \code + EnvFunction DragForce(&myDisturbanceFunction); +* \endcode +* and then fill out the parameter list: +* \code + DragForce.AddParameter(reinterpret_cast(*CrossArea), 1); +* \endcode +* Notice it is important to only give a pointer to a value that will +* stay "in scope" as long as needed for the simulation. Also, the +* reinterpret_cast() is needed to make the value 'look like' a void +* pointer. Don't worry too much about this, but read Stroustrop if +* you'd like to know more. +* +* \par Example disturbance function: + \code +// Force function that will be called each timestep +Vector DragForceFunction(const ssfTime* _currentTime, const OrbitState* _currentOrbitState, const AttitudeState* _currentAttitudeState, EnvFuncParamaterType _parameterList) +{ + Vector Forces(3); + double BC = *(reinterpret_cast(_parameterList[1])); + double Density = *(reinterpret_cast(_parameterList[2])); // kg/m^3 + Vector Vrel(3); Vrel = _currentOrbitState->GetState()(_(VectorIndexBase+3,VectorIndexBase+5)); + double Vrel_mag = norm2(Vrel); + Forces = -1/2 * rho / BC * pow(Vrel_mag,2) * Vrel / Vrel_mag; + return Forces; +} + \endcode +* +* \example testEnvironment.cpp +* Example using an Environment object for integration. +* +* \example testPropagation.cpp +* Example propagation of a combined satellite orbit \& attitude. +*/ +class EnvFunction +{ +public: + EnvFunction(pt2EnvFunc _EnvFuncPtr); + + EnvFunction(pt2EnvFunc _EnvFuncPtr, const int & _numParameters); + + Vector Evaluate(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState); + + void AddParameter(void* _parameter, int _paramNumber = -1); + + void RemoveParameter(int _paramNumber = -1); + + void ChangeParameter(void* _parameter, int _paramNumber = -1); +private: + /*! \brief internal pointer to the environmental disturbance function */ + pt2EnvFunc m_EnvFuncPtr; + /*! \brief internal storage of the number of parameters in the list */ + int m_NumParameters; + /*! \brief list of pointers to the parameters */ + EnvFuncParamaterType m_EnvFuncParameters; + +}; + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup EnvironmentForceFunctions Environment Force Disturbance Functions +* @ingroup EnvironmentToolkit +* +* +*/ +/*! @defgroup EnvironmentTorqueFunctions Environment Torque Disturbance Functions +* @ingroup EnvironmentToolkit +* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +/*!\brief Encapsulation of a spacecraft environment (disturbance forces, torques, central body, etc.) +* \ingroup EnvironmentToolkit Environment Toolkit +* +* The Environment class is used to contain all the different aspects of the external +* environment of the spacecraft. This currently includes disturbance forces (gravity, drag, solar radiation pressure), +* disturbance torques (gravity gradient, magnetic dipole, fuel slosh), and central body (for constants). +* +* To use the Environment class, the user should create (or include) and assign the desired force and torque +* disturbance functions (EnvFunction), and CentralBody. The integrator or propagator would then use the GetTorque() and +* GetForce() functions to modify the dynamics. +* +* \par Example: + \code + * Environment* pEarthEnv = new Environment; + * EarthCentralBody *pCBEarth = new EarthCentralBody; + * pEarthEnv->SetCentralBody(pCBEarth); + + * // Add Gravity force function + * EnvFunction TwoBodyGravity(&GravityForceFunction); + * double Mass = 100; \\kg + * TwoBodyGravity.AddParameter(reinterpret_cast(&Mass), 1); + * pEarthEnv->AddForceFunction(TwoBodyGravity); + + * // Add Drag Force Function + * EnvFunction DragForce(&DragForceFunction); + * double BallisticCoefficient = 200; + * DragForce.AddParameter(reinterpret_cast(&BallisticCoefficient), 1); + * pEarthEnv->AddForceFunction(DragForce); + + * // Add Magnetic Dipole + * EnvFunction MagDipole(&MagneticDipoleFunction); + * MagDiple.AddParameter(reinterpret_cast(&Spacecraft.GetDipole(), 1); + * pEarthEnv->AddTorqueFunction(MagDipole); + \endcode +* +*/ +class Environment +{ +public: + Environment(); + + virtual ~Environment(); + + Vector GetTorques(const ssfTime& _currentTime, const OrbitState& _currentOrbitState, const AttitudeState& _currentAttitudeState); + + Vector GetForces(const ssfTime& _currentTime, const OrbitState& _currentOrbitState, const AttitudeState& _currentAttitudeState); + + void AddForceFunction(const EnvFunction &_forceFunc); + + void AddTorqueFunction(const EnvFunction &_torqueFunc); + + const Functor& GetForceFunction() const; + + const Functor& GetTorqueFunction() const; + + void SetCentralBody(CentralBody *_pCB); + + const CentralBody* GetCentralBody() const; + +private: + /*! \brief internal vector of the pointers to the force disturbance functions */ + vector m_ForceFunctions; + /*! \brief internal vector of the pointers to the torque disturbance functions */ + vector m_TorqueFunctions; + /*! \brief internal iterator for stepping through the disturbance function vectors */ + vector::iterator m_funcIterator; + /*! \brief internal pointer to the environment central body */ + CentralBody *m_pCB; + + /*! \brief internal Vector of the most recent calculated disturbance forces */ + Vector m_CalculatedForces; + /*! \brief internal Vector of the most recent calculated disturbance torques */ + Vector m_CalculatedTorques; + /*! \brief internal pointer to the Environment::GetForces() function */ + ObjectFunctor m_ForcesFunctor; + /*! \brief internal pointer to the Environment::GetTorques() function */ + ObjectFunctor m_TorquesFunctor; + + +}; +} // close namespace O_SESSAME +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Environment.h,v $ +* Revision 1.13 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.12 2003/06/12 18:06:35 nilspace +* . +* +* Revision 1.11 2003/06/10 14:48:03 nilspace +* Changed include CentralBody.h to look in CentralBody directory. +* +* Revision 1.10 2003/06/06 17:35:52 nilspace +* Moved to CentralBody directory. +* +* Revision 1.9 2003/05/22 21:04:16 nilspace +* Updated comments. +* +* Revision 1.8 2003/05/22 03:42:32 nilspace +* Moved documentation to the implementation file. +* +* Revision 1.7 2003/05/20 17:51:12 nilspace +* Updated comments. +* +* Revision 1.6 2003/05/13 18:59:16 nilspace +* Fixed some comments. +* +* Revision 1.5 2003/05/05 20:45:46 nilspace +* Changed the pass-by-address parameters to pass-by-reference. +* +* Revision 1.4 2003/05/02 16:16:28 nilspace +* Documented the API. +* +* Revision 1.3 2003/05/02 02:16:29 nilspace +* Documented the API. +* Added a GetTorquesFunction(). +* +* Revision 1.2 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.1 2003/04/08 22:37:22 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/environment/Jamfile b/src/environment/Jamfile new file mode 100644 index 0000000..9b1d1e5 --- /dev/null +++ b/src/environment/Jamfile @@ -0,0 +1,29 @@ +########################################### +# Environment Jamfile +# +# $Author: simpliciter $ +# $Revision: 1.3 $ +# $Date: 2003/12/08 14:48:27 $ +########################################### + +SubDir OPENSESSAME_ROOT src environment ; + +Objects Environment.cpp CentralBody$(SLASH)CentralBody.cpp CentralBody$(SLASH)EarthCentralBody.cpp CentralBody$(SLASH)Models$(SLASH)TiltedDipoleMagneticModel.cpp ; +ObjectHdrs Environment.cpp CentralBody$(SLASH)CentralBody.cpp CentralBody$(SLASH)EarthCentralBody.cpp CentralBody$(SLASH)Models$(SLASH)TiltedDipoleMagneticModel.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)environment : Environment$(SUFOBJ) CentralBody$(SLASH)CentralBody$(SUFOBJ) CentralBody$(SLASH)EarthCentralBody$(SUFOBJ) CentralBody$(SLASH)Models$(SLASH)TiltedDipoleMagneticModel$(SUFOBJ) : $(OPENSESSAME_HDRS) ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)environment$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : Environment.h CentralBody$(SLASH)CentralBody.h CentralBody$(SLASH)EarthCentralBody.h CentralBody$(SLASH)Models$(SLASH)MagneticModel.h CentralBody$(SLASH)Models$(SLASH)TiltedDipoleMagneticModel.h Disturbances$(SLASH)GravityFunctions.h Disturbances$(SLASH)SolarDisturbances.h Disturbances$(SLASH)ThirdBodyDisturbances.h ; + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.3 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# ******************************************************************************/ + + + diff --git a/src/environment/Makefile b/src/environment/Makefile new file mode 100644 index 0000000..8892d6e --- /dev/null +++ b/src/environment/Makefile @@ -0,0 +1,232 @@ +############################################################################# +# Makefile for building: ../../lib/libosessame_environment.a +# Generated by qmake (1.02a) on: Sat Oct 18 17:32:56 2003 +# Project: environment.pro +# Template: lib +# Command: $(QMAKE) environment.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +LEX = flex +YACC = yacc +CFLAGS = -pipe -Wall -W -g +CXXFLAGS = -pipe -Wall -W -g +LEXFLAGS = +YACCFLAGS= -d +INCPATH = -I../matrix -I../rotation -I../attitude -I../orbit -I../datahandling -I../dynamics -I../environment -I.. -ICentralBody -ICentralBody/Models -I$(QTDIR)/mkspecs/default +AR = ar cqs +RANLIB = +MOC = $(QTDIR)/bin/moc +UIC = $(QTDIR)/bin/uic +QMAKE = qmake +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE= $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = +DEL_DIR = +MOVE = mv + +####### Output directory + +OBJECTS_DIR = ../../objects/ + +####### Files + +HEADERS = CentralBody/EarthCentralBody.h \ + CentralBody/CentralBody.h \ + CentralBody/Models/TiltedDipoleMagneticModel.h \ + CentralBody/Models/MagneticModel.h \ + Environment.h +SOURCES = CentralBody/CentralBody.cpp \ + CentralBody/EarthCentralBody.cpp \ + Environment.cpp \ + CentralBody/Models/TiltedDipoleMagneticModel.cpp +OBJECTS = ../../objects/CentralBody.o \ + ../../objects/EarthCentralBody.o \ + ../../objects/Environment.o \ + ../../objects/TiltedDipoleMagneticModel.o +FORMS = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = +DIST = +QMAKE_TARGET = osessame_environment +DESTDIR = ../../lib/ +TARGET = ../../lib/libosessame_environment.a + +first: all +####### Implicit rules + +.SUFFIXES: .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: Makefile $(TARGET) + +staticlib: $(TARGET) + +$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) + test -d ../../lib/ || mkdir -p ../../lib/ + -rm -f $(TARGET) + $(AR) $(TARGET) $(OBJECTS) $(OBJMOC) + + +mocables: $(SRCMOC) + +$(MOC): + ( cd $(QTDIR)/src/moc ; $(MAKE) ) + +Makefile: environment.pro $(QTDIR)/mkspecs/default/qmake.conf + $(QMAKE) environment.pro +qmake: + @$(QMAKE) environment.pro + +dist: + @mkdir -p ../../objects/osessame_environment && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) ../../objects/osessame_environment/ && ( cd `dirname ../../objects/osessame_environment` && $(TAR) osessame_environment.tar osessame_environment && $(GZIP) osessame_environment.tar ) && mv `dirname ../../objects/osessame_environment`/osessame_environment.tar.gz . && rm -rf ../../objects/osessame_environment + +uiclean: + +clean: + -rm -f $(OBJECTS) + -rm -f *~ core *.core + + +####### Sub-libraries + +distclean: clean + -rm -f ../../lib/$(TARGET) $(TARGET) + + +FORCE: + +####### Compile + +../../objects/CentralBody.o: CentralBody/CentralBody.cpp CentralBody/CentralBody.h \ + CentralBody/Models/MagneticModel.h \ + ../rotation/Rotation.h \ + ../matrix/Matrix.h \ + ../orbit/OrbitState.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/CentralBody.o CentralBody/CentralBody.cpp + +../../objects/EarthCentralBody.o: CentralBody/EarthCentralBody.cpp CentralBody/EarthCentralBody.h \ + ../rotation/Rotation.h \ + CentralBody/CentralBody.h \ + ../matrix/Matrix.h \ + ../orbit/OrbitState.h \ + CentralBody/Models/MagneticModel.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/EarthCentralBody.o CentralBody/EarthCentralBody.cpp + +../../objects/Environment.o: Environment.cpp Environment.h \ + CentralBody/CentralBody.h \ + ../rotation/Rotation.h \ + ../matrix/Matrix.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/OrbitState.h \ + CentralBody/Models/MagneticModel.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/Environment.o Environment.cpp + +../../objects/TiltedDipoleMagneticModel.o: CentralBody/Models/TiltedDipoleMagneticModel.cpp CentralBody/Models/TiltedDipoleMagneticModel.h \ + CentralBody/Models/MagneticModel.h \ + ../matrix/Matrix.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/TiltedDipoleMagneticModel.o CentralBody/Models/TiltedDipoleMagneticModel.cpp + +####### Install + +install: all + +uninstall: + diff --git a/src/environment/environment.pro b/src/environment/environment.pro new file mode 100644 index 0000000..3e00a42 --- /dev/null +++ b/src/environment/environment.pro @@ -0,0 +1,34 @@ +# +# $Id: environment.pro,v 1.5 2003/10/18 21:37:28 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = CentralBody/*.h\ + CentralBody/Models/*.h\ + Environment.h +SOURCES = CentralBody/CentralBody.cpp\ + CentralBody/EarthCentralBody.cpp\ + Environment.cpp \ + CentralBody/Models/TiltedDipoleMagneticModel.cpp + +TARGET = osessame_environment +VERSION = 1.0 + + +DESTDIR = ../../lib/ +INCLUDEPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment .. CentralBody \ + CentralBody/Models +CONFIG = staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment ../utils diff --git a/src/kinematics/CVS/Entries b/src/kinematics/CVS/Entries new file mode 100644 index 0000000..53c6311 --- /dev/null +++ b/src/kinematics/CVS/Entries @@ -0,0 +1,2 @@ +/QuaternionKinematics.h/1.2/Wed Apr 23 16:30:58 2003// +D diff --git a/src/kinematics/CVS/Repository b/src/kinematics/CVS/Repository new file mode 100644 index 0000000..c0788ca --- /dev/null +++ b/src/kinematics/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/kinematics diff --git a/src/kinematics/CVS/Root b/src/kinematics/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/kinematics/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/kinematics/QuaternionKinematics.h b/src/kinematics/QuaternionKinematics.h new file mode 100644 index 0000000..147ff19 --- /dev/null +++ b/src/kinematics/QuaternionKinematics.h @@ -0,0 +1,37 @@ +//////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file QuaternionKinematics.h +* \brief Rigid body kinematic equations of attitude motion in quaternion form. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/04/23 16:30:58 $ +////////////////////////////////////////////////////////////////////////////////////////////////// +* \todo document the QuaternionKinematics class +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef QUATERNIONKINEMATICS_H +#define QUATERNIONKINEMATICS_H +#include "../rotation/Rotation.h" + +static Vector QuaternionKinematics(const double &_time, const Vector &_qIn, const Matrix &_wIn) +{ + Matrix qtemp(4,3); + qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(_qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + _qIn(VectorIndexBase+3) * eye(3); + qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~_qIn(_(VectorIndexBase+0,VectorIndexBase+2))); + + qtemp.initialize(0.5 * qtemp * _wIn); + Vector qDot(QUATERNION_SIZE);qDot(_) = qtemp(_,MatrixIndexBase); + return (Vector)qDot; +} + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: QuaternionKinematics.h,v $ +* Revision 1.2 2003/04/23 16:30:58 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/03/25 02:28:20 nilspace +* initial submission. Needs to be verified. +* +******************************************************************************/ diff --git a/src/matrix/CVS/Entries b/src/matrix/CVS/Entries new file mode 100644 index 0000000..39f701e --- /dev/null +++ b/src/matrix/CVS/Entries @@ -0,0 +1,55 @@ +/Jamfile/1.6/Tue Dec 9 04:35:15 2003// +/Makefile/1.3/Sat Oct 18 21:37:28 2003// +/Matrix.h/1.5/Fri Jul 14 02:11:47 2006// +/access.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/arraybse.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/arraybse.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/arraygph.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/arrayops.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/arrayutl.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/bnengine.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/cammva.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/camtype.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/darray.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/darray.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/datahndl.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/datahndl.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/dbengnea.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/dbengneb.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/dmatrix.cpp/1.1.1.1/Thu Feb 27 18:55:55 2003// +/dmatrix.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/dvector.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/makeGraphics/1.1.1.1/Thu Feb 27 18:55:55 2003// +/makeGraphicsGPP/1.1.1.1/Thu Feb 27 18:55:55 2003// +/makeSamples/1.1.1.1/Thu Feb 27 18:55:55 2003// +/makeSamplesGPP/1.1.1.1/Thu Feb 27 18:55:55 2003// +/matbse.cpp/1.2/Tue Mar 25 02:32:36 2003// +/matbse.h/1.1.1.1/Thu Feb 27 18:55:55 2003// +/matgph.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/matrix.pro/1.3/Fri Dec 5 15:43:30 2003// +/matutl.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvaexit.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvaexit.h/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvagph.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvagph.h/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvaimpexp.h/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvalngbase.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvalngbase.h/1.2/Fri Apr 25 13:49:37 2003// +/mvasamp1.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvasamp2.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvasamp3.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/mvasamp4.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/range.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/range.h/1.1.1.1/Thu Feb 27 18:55:56 2003// +/rangetst1.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/strctbse.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/strctbse.h/1.1.1.1/Thu Feb 27 18:55:56 2003// +/typehndl.h/1.2/Fri Apr 25 14:44:47 2003// +/under.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/under.h/1.1.1.1/Thu Feb 27 18:55:56 2003// +/vecbse.cpp/1.2/Tue Mar 25 02:32:36 2003// +/vecbse.h/1.1.1.1/Thu Feb 27 18:55:56 2003// +/vecgph.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +/vecutl.cpp/1.1.1.1/Thu Feb 27 18:55:56 2003// +D/camblas//// +D/camlapack//// diff --git a/src/matrix/CVS/Repository b/src/matrix/CVS/Repository new file mode 100644 index 0000000..d9e74c0 --- /dev/null +++ b/src/matrix/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/matrix diff --git a/src/matrix/CVS/Root b/src/matrix/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/matrix/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/matrix/Jamfile b/src/matrix/Jamfile new file mode 100644 index 0000000..221ba9d --- /dev/null +++ b/src/matrix/Jamfile @@ -0,0 +1,46 @@ +############################################ +# +# Jamfile for the CAMMatrix Library Objects +# +# $Author: simpliciter $ +# $Revision: 1.6 $ +# $Date: 2003/12/09 04:35:15 $ +########################################### + + +# Location of this Jamfile +SubDir OPENSESSAME_ROOT src matrix ; + +CAMMATRIX_HDRS = $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)matrix $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)matrix$(SLASH)camblas $(OPENSESSAME_ROOT)$(SLASH)src$(SLASH)matrix$(SLASH)camlapack ; + +FILELIST = arraybse.cpp arrayops.cpp arrayutl.cpp darray.cpp datahndl.cpp dbengnea.cpp dbengneb.cpp dmatrix.cpp matbse.cpp matutl.cpp mvaexit.cpp mvalngbase.cpp range.cpp rangetst1.cpp strctbse.cpp under.cpp vecbse.cpp vecutl.cpp camblas/blas.cpp camblas/dasum.c camblas/daxpy.c camblas/dcopy.c camblas/ddot.c camblas/dgemm.c camblas/dgemv.c camblas/dger.c camblas/dnrm2.c camblas/drot.c camblas/dscal.c camblas/dswap.c camblas/dsymv.c camblas/dsyr2.c camblas/dsyr2k.c camblas/dtrmm.c camblas/dtrmv.c camblas/ilaenv.c camblas/lsame.c camblas/s_cmp.c camblas/s_copy.c camblas/xerbla.c camlapack/d_lg10.c camlapack/d_sign.c camlapack/dgecon.c camlapack/dgeequ.c camlapack/dgerfs.c camlapack/dgesvx.c camlapack/dgetf2.c camlapack/dgetrf.c camlapack/dgetrs.c camlapack/dlabad.c camlapack/dlacon.c camlapack/dlacpy.c camlapack/dlamch.c camlapack/dlange.c camlapack/dlaqge.c camlapack/dlassq.c camlapack/dlaswp.c camlapack/dlatrs.c camlapack/drscl.c camlapack/dtrsm.c camlapack/dtrsv.c camlapack/i_dnnt.c camlapack/idamax.c camlapack/ilaenv.c camlapack/pow_di.c camlapack/s_cmp.c camlapack/s_copy.c ; + +Objects $(FILELIST) ; +ObjectHdrs $(FILELIST) : $(CAMMATRIX_HDRS) ; + +LibraryFromObjects $(PFXLIB)matrix : arraybse.o arrayops.o arrayutl.o darray.o datahndl.o dbengnea.o dbengneb.o dmatrix.o matbse.o matutl.o mvaexit.o mvalngbase.o range.o rangetst1.o strctbse.o under.o vecbse.o vecutl.o camblas/blas.o camblas/dasum.o camblas/daxpy.o camblas/dcopy.o camblas/ddot.o camblas/dgemm.o camblas/dgemv.o camblas/dger.o camblas/dnrm2.o camblas/drot.o camblas/dscal.o camblas/dswap.o camblas/dsymv.o camblas/dsyr2.o camblas/dsyr2k.o camblas/dtrmm.o camblas/dtrmv.o camblas/ilaenv.o camblas/lsame.o camblas/s_cmp.o camblas/s_copy.o camblas/xerbla.o camlapack/d_lg10.o camlapack/d_sign.o camlapack/dgecon.o camlapack/dgeequ.o camlapack/dgerfs.o camlapack/dgesvx.o camlapack/dgetf2.o camlapack/dgetrf.o camlapack/dgetrs.o camlapack/dlabad.o camlapack/dlacon.o camlapack/dlacpy.o camlapack/dlamch.o camlapack/dlange.o camlapack/dlaqge.o camlapack/dlassq.o camlapack/dlaswp.o camlapack/dlatrs.o camlapack/drscl.o camlapack/dtrsm.o camlapack/dtrsv.o camlapack/i_dnnt.o camlapack/idamax.o camlapack/ilaenv.o camlapack/pow_di.o camlapack/s_cmp.o camlapack/s_copy.o ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)matrix$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : Matrix.h ; + +#SubInclude OPENSESSAME_ROOT src matrix camblas ; +#SubInclude OPENSESSAME_ROOT src matrix camlapack ; + + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.6 2003/12/09 04:35:15 simpliciter +# * Includes all of the correct files now. Needs to be edited for M$ Windows compatibility. +# * +# * Revision 1.5 2003/12/09 00:59:55 simpliciter +# * New and improved. +# * +# * Revision 1.4 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# ******************************************************************************/ + + + diff --git a/src/matrix/Makefile b/src/matrix/Makefile new file mode 100644 index 0000000..b6487a2 --- /dev/null +++ b/src/matrix/Makefile @@ -0,0 +1,584 @@ +############################################################################# +# Makefile for building: ../../lib/libosessame_matrix.a +# Generated by qmake (1.02a) on: Sat Oct 18 17:32:55 2003 +# Project: matrix.pro +# Template: lib +# Command: $(QMAKE) matrix.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +LEX = flex +YACC = yacc +CFLAGS = -pipe -Wall -W -g +CXXFLAGS = -pipe -Wall -W -g +LEXFLAGS = +YACCFLAGS= -d +INCPATH = -Icamblas -Icamlapack -I$(QTDIR)/mkspecs/default +AR = ar cqs +RANLIB = +MOC = $(QTDIR)/bin/moc +UIC = $(QTDIR)/bin/uic +QMAKE = qmake +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE= $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = +DEL_DIR = +MOVE = mv + +####### Output directory + +OBJECTS_DIR = ../../objects/ + +####### Files + +HEADERS = arraybse.h \ + bnengine.h \ + cammva.h \ + camtype.h \ + darray.h \ + datahndl.h \ + dmatrix.h \ + dvector.h \ + matbse.h \ + Matrix.h \ + mvaexit.h \ + mvagph.h \ + mvaimpexp.h \ + mvalngbase.h \ + range.h \ + strctbse.h \ + typehndl.h \ + under.h \ + vecbse.h \ + access.h \ + camblas/blasimpexp.h \ + camblas/cblasimpexp.h \ + camblas/f2c.h \ + camblas/blas.h \ + camlapack/f2c.h \ + camlapack/camlaimpexp.h +SOURCES = arraybse.cpp \ + arrayutl.cpp \ + datahndl.cpp \ + dbengnea.cpp \ + dbengneb.cpp \ + dmatrix.cpp \ + matbse.cpp \ + matutl.cpp \ + mvaexit.cpp \ + mvalngbase.cpp \ + range.cpp \ + strctbse.cpp \ + under.cpp \ + vecbse.cpp \ + vecutl.cpp \ + camblas/daxpy.c \ + camblas/dcopy.c \ + camblas/ddot.c \ + camblas/dgemm.c \ + camblas/dgemv.c \ + camblas/dger.c \ + camblas/dnrm2.c \ + camblas/drot.c \ + camblas/dscal.c \ + camblas/dswap.c \ + camblas/dsymv.c \ + camblas/dsyr2.c \ + camblas/dsyr2k.c \ + camblas/dtrmm.c \ + camblas/dtrmv.c \ + camblas/ilaenv.c \ + camblas/lsame.c \ + camblas/s_cmp.c \ + camblas/s_copy.c \ + camblas/xerbla.c \ + camblas/dasum.c \ + camblas/blas.cpp \ + camlapack/d_sign.c \ + camlapack/dgecon.c \ + camlapack/dgeequ.c \ + camlapack/dgerfs.c \ + camlapack/dgesvx.c \ + camlapack/dgetf2.c \ + camlapack/dgetrf.c \ + camlapack/dgetrs.c \ + camlapack/dlabad.c \ + camlapack/dlacon.c \ + camlapack/dlacpy.c \ + camlapack/dlamch.c \ + camlapack/dlange.c \ + camlapack/dlaqge.c \ + camlapack/dlassq.c \ + camlapack/dlaswp.c \ + camlapack/dlatrs.c \ + camlapack/drscl.c \ + camlapack/dtrsm.c \ + camlapack/dtrsv.c \ + camlapack/i_dnnt.c \ + camlapack/idamax.c \ + camlapack/ilaenv.c \ + camlapack/pow_di.c \ + camlapack/s_cmp.c \ + camlapack/s_copy.c \ + camlapack/d_lg10.c +OBJECTS = ../../objects/arraybse.o \ + ../../objects/arrayutl.o \ + ../../objects/datahndl.o \ + ../../objects/dbengnea.o \ + ../../objects/dbengneb.o \ + ../../objects/dmatrix.o \ + ../../objects/matbse.o \ + ../../objects/matutl.o \ + ../../objects/mvaexit.o \ + ../../objects/mvalngbase.o \ + ../../objects/range.o \ + ../../objects/strctbse.o \ + ../../objects/under.o \ + ../../objects/vecbse.o \ + ../../objects/vecutl.o \ + ../../objects/daxpy.o \ + ../../objects/dcopy.o \ + ../../objects/ddot.o \ + ../../objects/dgemm.o \ + ../../objects/dgemv.o \ + ../../objects/dger.o \ + ../../objects/dnrm2.o \ + ../../objects/drot.o \ + ../../objects/dscal.o \ + ../../objects/dswap.o \ + ../../objects/dsymv.o \ + ../../objects/dsyr2.o \ + ../../objects/dsyr2k.o \ + ../../objects/dtrmm.o \ + ../../objects/dtrmv.o \ + ../../objects/ilaenv.o \ + ../../objects/lsame.o \ + ../../objects/s_cmp.o \ + ../../objects/s_copy.o \ + ../../objects/xerbla.o \ + ../../objects/dasum.o \ + ../../objects/blas.o \ + ../../objects/d_sign.o \ + ../../objects/dgecon.o \ + ../../objects/dgeequ.o \ + ../../objects/dgerfs.o \ + ../../objects/dgesvx.o \ + ../../objects/dgetf2.o \ + ../../objects/dgetrf.o \ + ../../objects/dgetrs.o \ + ../../objects/dlabad.o \ + ../../objects/dlacon.o \ + ../../objects/dlacpy.o \ + ../../objects/dlamch.o \ + ../../objects/dlange.o \ + ../../objects/dlaqge.o \ + ../../objects/dlassq.o \ + ../../objects/dlaswp.o \ + ../../objects/dlatrs.o \ + ../../objects/drscl.o \ + ../../objects/dtrsm.o \ + ../../objects/dtrsv.o \ + ../../objects/i_dnnt.o \ + ../../objects/idamax.o \ + ../../objects/ilaenv.o \ + ../../objects/pow_di.o \ + ../../objects/s_cmp.o \ + ../../objects/s_copy.o \ + ../../objects/d_lg10.o +FORMS = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = +DIST = +QMAKE_TARGET = osessame_matrix +DESTDIR = ../../lib/ +TARGET = ../../lib/libosessame_matrix.a + +first: all +####### Implicit rules + +.SUFFIXES: .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: Makefile $(TARGET) + +staticlib: $(TARGET) + +$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) + test -d ../../lib/ || mkdir -p ../../lib/ + -rm -f $(TARGET) + $(AR) $(TARGET) $(OBJECTS) $(OBJMOC) + + +mocables: $(SRCMOC) + +$(MOC): + ( cd $(QTDIR)/src/moc ; $(MAKE) ) + +Makefile: matrix.pro $(QTDIR)/mkspecs/default/qmake.conf + $(QMAKE) matrix.pro +qmake: + @$(QMAKE) matrix.pro + +dist: + @mkdir -p ../../objects/osessame_matrix && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) ../../objects/osessame_matrix/ && ( cd `dirname ../../objects/osessame_matrix` && $(TAR) osessame_matrix.tar osessame_matrix && $(GZIP) osessame_matrix.tar ) && mv `dirname ../../objects/osessame_matrix`/osessame_matrix.tar.gz . && rm -rf ../../objects/osessame_matrix + +uiclean: + +clean: + -rm -f $(OBJECTS) + -rm -f *~ core *.core + + +####### Sub-libraries + +distclean: clean + -rm -f ../../lib/$(TARGET) $(TARGET) + + +FORCE: + +####### Compile + +../../objects/arraybse.o: arraybse.cpp arraybse.h \ + vecbse.h \ + matbse.h \ + bnengine.h \ + strctbse.h \ + datahndl.h \ + access.h \ + mvaexit.h \ + camtype.h \ + typehndl.h \ + mvaimpexp.h \ + mvalngbase.h \ + range.h \ + under.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/arraybse.o arraybse.cpp + +../../objects/arrayutl.o: arrayutl.cpp arraybse.h \ + bnengine.h \ + strctbse.h \ + datahndl.h \ + access.h \ + mvaexit.h \ + camtype.h \ + typehndl.h \ + mvaimpexp.h \ + mvalngbase.h \ + range.h \ + under.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/arrayutl.o arrayutl.cpp + +../../objects/datahndl.o: datahndl.cpp datahndl.h \ + mvaexit.h \ + camtype.h \ + mvaimpexp.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/datahndl.o datahndl.cpp + +../../objects/dbengnea.o: dbengnea.cpp bnengine.h \ + strctbse.h \ + datahndl.h \ + mvaimpexp.h \ + mvalngbase.h \ + access.h \ + mvaexit.h \ + range.h \ + under.h \ + camtype.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/dbengnea.o dbengnea.cpp + +../../objects/dbengneb.o: dbengneb.cpp bnengine.h \ + strctbse.h \ + datahndl.h \ + mvaimpexp.h \ + mvalngbase.h \ + access.h \ + mvaexit.h \ + range.h \ + under.h \ + camtype.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/dbengneb.o dbengneb.cpp + +../../objects/dmatrix.o: dmatrix.cpp dmatrix.h \ + strctbse.h \ + datahndl.h \ + matbse.h \ + vecbse.h \ + range.h \ + camtype.h \ + under.h \ + mvaimpexp.h \ + mvalngbase.h \ + access.h \ + mvaexit.h \ + typehndl.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/dmatrix.o dmatrix.cpp + +../../objects/matbse.o: matbse.cpp arraybse.h \ + vecbse.h \ + matbse.h \ + bnengine.h \ + strctbse.h \ + datahndl.h \ + access.h \ + mvaexit.h \ + camtype.h \ + typehndl.h \ + mvaimpexp.h \ + mvalngbase.h \ + range.h \ + under.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/matbse.o matbse.cpp + +../../objects/matutl.o: matutl.cpp dmatrix.h \ + bnengine.h \ + strctbse.h \ + datahndl.h \ + matbse.h \ + vecbse.h \ + range.h \ + camtype.h \ + under.h \ + mvaimpexp.h \ + mvalngbase.h \ + access.h \ + mvaexit.h \ + typehndl.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/matutl.o matutl.cpp + +../../objects/mvaexit.o: mvaexit.cpp mvaexit.h \ + mvaimpexp.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/mvaexit.o mvaexit.cpp + +../../objects/mvalngbase.o: mvalngbase.cpp mvalngbase.h \ + mvaimpexp.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/mvalngbase.o mvalngbase.cpp + +../../objects/range.o: range.cpp range.h \ + mvaexit.h \ + mvaimpexp.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/range.o range.cpp + +../../objects/strctbse.o: strctbse.cpp strctbse.h \ + mvalngbase.h \ + access.h \ + mvaexit.h \ + mvaimpexp.h \ + range.h \ + under.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/strctbse.o strctbse.cpp + +../../objects/under.o: under.cpp under.h \ + range.h \ + mvaimpexp.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/under.o under.cpp + +../../objects/vecbse.o: vecbse.cpp arraybse.h \ + vecbse.h \ + matbse.h \ + bnengine.h \ + strctbse.h \ + datahndl.h \ + access.h \ + mvaexit.h \ + camtype.h \ + typehndl.h \ + mvaimpexp.h \ + mvalngbase.h \ + range.h \ + under.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/vecbse.o vecbse.cpp + +../../objects/vecutl.o: vecutl.cpp vecbse.h \ + bnengine.h \ + strctbse.h \ + datahndl.h \ + access.h \ + mvaexit.h \ + camtype.h \ + typehndl.h \ + mvaimpexp.h \ + mvalngbase.h \ + range.h \ + under.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/vecutl.o vecutl.cpp + +../../objects/daxpy.o: camblas/daxpy.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/daxpy.o camblas/daxpy.c + +../../objects/dcopy.o: camblas/dcopy.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dcopy.o camblas/dcopy.c + +../../objects/ddot.o: camblas/ddot.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/ddot.o camblas/ddot.c + +../../objects/dgemm.o: camblas/dgemm.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgemm.o camblas/dgemm.c + +../../objects/dgemv.o: camblas/dgemv.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgemv.o camblas/dgemv.c + +../../objects/dger.o: camblas/dger.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dger.o camblas/dger.c + +../../objects/dnrm2.o: camblas/dnrm2.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dnrm2.o camblas/dnrm2.c + +../../objects/drot.o: camblas/drot.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/drot.o camblas/drot.c + +../../objects/dscal.o: camblas/dscal.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dscal.o camblas/dscal.c + +../../objects/dswap.o: camblas/dswap.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dswap.o camblas/dswap.c + +../../objects/dsymv.o: camblas/dsymv.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dsymv.o camblas/dsymv.c + +../../objects/dsyr2.o: camblas/dsyr2.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dsyr2.o camblas/dsyr2.c + +../../objects/dsyr2k.o: camblas/dsyr2k.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dsyr2k.o camblas/dsyr2k.c + +../../objects/dtrmm.o: camblas/dtrmm.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dtrmm.o camblas/dtrmm.c + +../../objects/dtrmv.o: camblas/dtrmv.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dtrmv.o camblas/dtrmv.c + +../../objects/ilaenv.o: camblas/ilaenv.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/ilaenv.o camblas/ilaenv.c + +../../objects/lsame.o: camblas/lsame.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/lsame.o camblas/lsame.c + +../../objects/s_cmp.o: camblas/s_cmp.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/s_cmp.o camblas/s_cmp.c + +../../objects/s_copy.o: camblas/s_copy.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/s_copy.o camblas/s_copy.c + +../../objects/xerbla.o: camblas/xerbla.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/xerbla.o camblas/xerbla.c + +../../objects/dasum.o: camblas/dasum.c camblas/f2c.h \ + camblas/cblasimpexp.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dasum.o camblas/dasum.c + +../../objects/blas.o: camblas/blas.cpp camblas/blas.h \ + camblas/blasimpexp.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/blas.o camblas/blas.cpp + +../../objects/d_sign.o: camlapack/d_sign.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/d_sign.o camlapack/d_sign.c + +../../objects/dgecon.o: camlapack/dgecon.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgecon.o camlapack/dgecon.c + +../../objects/dgeequ.o: camlapack/dgeequ.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgeequ.o camlapack/dgeequ.c + +../../objects/dgerfs.o: camlapack/dgerfs.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgerfs.o camlapack/dgerfs.c + +../../objects/dgesvx.o: camlapack/dgesvx.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgesvx.o camlapack/dgesvx.c + +../../objects/dgetf2.o: camlapack/dgetf2.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgetf2.o camlapack/dgetf2.c + +../../objects/dgetrf.o: camlapack/dgetrf.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgetrf.o camlapack/dgetrf.c + +../../objects/dgetrs.o: camlapack/dgetrs.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dgetrs.o camlapack/dgetrs.c + +../../objects/dlabad.o: camlapack/dlabad.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlabad.o camlapack/dlabad.c + +../../objects/dlacon.o: camlapack/dlacon.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlacon.o camlapack/dlacon.c + +../../objects/dlacpy.o: camlapack/dlacpy.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlacpy.o camlapack/dlacpy.c + +../../objects/dlamch.o: camlapack/dlamch.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlamch.o camlapack/dlamch.c + +../../objects/dlange.o: camlapack/dlange.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlange.o camlapack/dlange.c + +../../objects/dlaqge.o: camlapack/dlaqge.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlaqge.o camlapack/dlaqge.c + +../../objects/dlassq.o: camlapack/dlassq.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlassq.o camlapack/dlassq.c + +../../objects/dlaswp.o: camlapack/dlaswp.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlaswp.o camlapack/dlaswp.c + +../../objects/dlatrs.o: camlapack/dlatrs.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dlatrs.o camlapack/dlatrs.c + +../../objects/drscl.o: camlapack/drscl.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/drscl.o camlapack/drscl.c + +../../objects/dtrsm.o: camlapack/dtrsm.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dtrsm.o camlapack/dtrsm.c + +../../objects/dtrsv.o: camlapack/dtrsv.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/dtrsv.o camlapack/dtrsv.c + +../../objects/i_dnnt.o: camlapack/i_dnnt.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/i_dnnt.o camlapack/i_dnnt.c + +../../objects/idamax.o: camlapack/idamax.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/idamax.o camlapack/idamax.c + +../../objects/ilaenv.o: camlapack/ilaenv.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/ilaenv.o camlapack/ilaenv.c + +../../objects/pow_di.o: camlapack/pow_di.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/pow_di.o camlapack/pow_di.c + +../../objects/s_cmp.o: camlapack/s_cmp.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/s_cmp.o camlapack/s_cmp.c + +../../objects/s_copy.o: camlapack/s_copy.c + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/s_copy.o camlapack/s_copy.c + +../../objects/d_lg10.o: camlapack/d_lg10.c camlapack/f2c.h + $(CC) -c $(CFLAGS) $(INCPATH) -o ../../objects/d_lg10.o camlapack/d_lg10.c + +####### Install + +install: all + +uninstall: + diff --git a/src/matrix/Matrix.h b/src/matrix/Matrix.h new file mode 100644 index 0000000..34355d0 --- /dev/null +++ b/src/matrix/Matrix.h @@ -0,0 +1,133 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Matrix.h +* \brief Wrapper of CammVa Matrix & Matrix Library. +* \author Andrew Turner +* \version 0.1 +* \date 2003 +////////////////////////////////////////////////////////////////////////////////////////////////// +* \todo Add overloading of operators +* \todo Reference cammva documentation +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef MATRIX_H +#define MATRIX_H + +#include +#include + +#include "cammva.h" +namespace O_SESSAME { + +const int MatrixIndexBase = 1; /*!<< Beginning index of Matrix class */ +const int VectorIndexBase = 1; /*!<< Beginning index of Vector class */ +const int MatrixRowsIndex = 1; /*!<< Value referring to the "rows" index */ +const int MatrixColsIndex = 2; /*!<< Value referring to the "columns" index */ +typedef CAMdoubleMatrix Matrix; /*!<< Encapsulation of CAMdoubleMatrix class */ +typedef CAMdoubleVector Vector; /*!<< Encapsulation of CAMdoubleVector class */ + +/** Creates an square identity matrix of specified size. +* @param _rowColumns Number of rows and columns to size matrix (will be a square matrix). +* \todo Implement eye as part of Vector or CAMdoubleVector class +*/ +inline Matrix eye(int _rowColumns) +{ + Matrix eyeOutput(_rowColumns,_rowColumns); + eyeOutput.setToValue(0.0); + for(int ii = MatrixIndexBase;ii < _rowColumns + MatrixIndexBase; ++ii) + eyeOutput(ii,ii) = 1.0; + return eyeOutput; +} + +/** Calculates the trace of matrix (sum of elements along diagonal). +* @param _inMatrix Matrix to have trace calculated. +* \todo Implement trace as part of Vector or CAMdoubleVector class +*/ +inline double trace(const Matrix &_inMatrix) +{ + double Sum = 0; + for(int ii = MatrixIndexBase;ii < _inMatrix[MatrixRowsIndex].getIndexCount() + MatrixIndexBase; ++ii) + Sum += _inMatrix(ii,ii); + return Sum; +} + +/** Calculates the 2-norm of the vector (square-root of the sum of the squares). +* \todo Implement norm2 as part of Vector or CAMdoubleVector class +* @param _inVector Vector to calculate the 2-norm of. +* @return Square-root of the sum of squares of elements in vector. +*/ +inline double norm2(const Vector &_inVector) +{ + double Sum = 0; + for(int ii = VectorIndexBase;ii < _inVector.getIndexCount() + VectorIndexBase; ++ii) + Sum += _inVector(ii) * _inVector(ii); + return sqrt(Sum); +} + +/** Normalizes a vector. + * @param _inVector Vector to be normalized. +* \todo Implement normalize as part of Vector or CAMdoubleVector class + */ +inline void normalize(Vector &_inVector) +{ + _inVector /= norm2(_inVector); + return; +} + +/** Calculates the Infinity-norm of the vector (largest value of the components). +* @param _inVector Vector to calculate the 2-norm of. +* @return Absolute value of maximum component in vector. +* \todo Implement normInf as part of Vector or CAMdoubleVector class +*/ +inline double normInf(const Vector &_inVector) +{ + return _inVector.maxAbs(); +} + +/** Calculates the skew-symmetric matrix of a vector. +* Equation: +/f[ + \bf{v^{\times}} = + \begin{bmatrix} + 0 & -v_3 & v_2\\ + v_3 & 0 & -v_1\\ + -v_2 & v_1 & 0 + \end{bmatrix} +/f] +* @param _inVector Vector to calculate the skew-symmetric matrix of. +* @return Skew-symmetric matrix (3x3). +* \todo Implement skew as part of Vector or CAMdoubleVector class +*/ +inline Matrix skew(const Vector &_inVector) +{ + Matrix Rout(3,3); + Rout.setToValue(0.0); + Rout(MatrixIndexBase+0,MatrixIndexBase+1) = + -_inVector(VectorIndexBase+2); + Rout(MatrixIndexBase+0,MatrixIndexBase+2) = + _inVector(VectorIndexBase+1); + Rout(MatrixIndexBase+1,MatrixIndexBase+0) = + _inVector(VectorIndexBase+2); + Rout(MatrixIndexBase+1,MatrixIndexBase+2) = + -_inVector(VectorIndexBase+0); + Rout(MatrixIndexBase+2,MatrixIndexBase+0) = + -_inVector(VectorIndexBase+1); + Rout(MatrixIndexBase+2,MatrixIndexBase+1) = + _inVector(VectorIndexBase+0); + return Rout; +} + +/** Calculates the cross product of 2 vectors. +* Equation: /f$ v_3 = v_1 \cross v_2 = v_1/f$ +* @param _inVector Vector to calculate the 2-norm of. +* @return Cross product of 2 vectors. +* \todo Implement crossP as part of Vector or CAMdoubleVector class +*/ +inline Vector crossP(const Vector &_v1, const Vector &_v2) +{ + return skew(_v1) * _v2; +} +} +#endif + + diff --git a/src/matrix/access.h b/src/matrix/access.h new file mode 100755 index 0000000..0c0c998 --- /dev/null +++ b/src/matrix/access.h @@ -0,0 +1,31 @@ +// +//****************************************************************************** +// ACCESS.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1996 +// +// Sept. 1996 +// +//******************************************************************************** +// + +#ifndef __CAMACCESS__ +#define __CAMACCESS__ + +#include "range.h" +#include "under.h" + +//__IMPEXP__ extern CAMunderscore _; +//__IMPEXP__ extern CAMrange CAMnullRange; +static CAMunderscore _; +static CAMrange CAMnullRange; + +#endif + + + + diff --git a/src/matrix/arraybse.cpp b/src/matrix/arraybse.cpp new file mode 100755 index 0000000..28e0f00 --- /dev/null +++ b/src/matrix/arraybse.cpp @@ -0,0 +1,1529 @@ +#include "arraybse.h" +#include "vecbse.h" +#include "matbse.h" +#include "bnengine.h" + +// +//*************************************************************** +// ARRAYBSE.CPP +//*************************************************************** +// +// +//***************************************************************** +// +// Chris Anderson +// +// Mon Sep 11 12:49:20 1995 +// +//***************************************************************** +// +// +//***************************************************************** +// CONSTRUCTORS +//***************************************************************** +// +// +//***************************************************************** +// +//***************************************************************** +// +CAMarrayBase::CAMarrayBase() +: Structure() +{ + DataP = 0; + typeValue = 0; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +CAMarrayBase::CAMarrayBase(int d_type) +: Structure() +{ + DataP = 0; + typeValue = d_type; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +CAMarrayBase::CAMarrayBase(const CAMarrayBase& A) +:Structure(A.Structure) +{ + if(A.DataP == 0) + {DataP = 0;} + else + { + if(A.referenceFlag == 1) + {DataP = A.DataP; } + else if(A.DataP->getTemporaryFlag() == 1) + { + DataP = new CAMdataHandler(*(A.DataP)); + DataP ->setReferenceCount(1); + } + else + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); + // + // copy based on type + // + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); + // + // + // + } + } + typeValue = A.typeValue; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +CAMarrayBase::CAMarrayBase(int d_type, const CAMrange& R1, const CAMrange& R2 , + const CAMrange& R3 , const CAMrange&R4 , + const CAMrange& R5 , const CAMrange&R6 , + const CAMrange& R7) +:Structure(R1,R2,R3,R4,R5,R6,R7) +{ + DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type); + DataP->setReferenceCount(1); + typeValue = d_type; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +// +//***************************************************************** +// DESTRUCTOR +//***************************************************************** +// +CAMarrayBase::~CAMarrayBase() +{ + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() < 0) + { + cerr << " Error : Reference Count < 0" << endl; + } + if(DataP->getReferenceCount() == 0) delete DataP; + } +} +// +//***************************************************************** +// ASSIGNMENT +//***************************************************************** +// +void CAMarrayBase::operator =(double value) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + Structure.initialize(_(1,1)); + DataP = new CAMdataHandler(1,CAMType::typeDouble); + DataP->setReferenceCount(1); + referenceFlag = 0; + arrayBaseReferenceCount = 0; + } + else + { + CAMstructureBase AStructure(_(1,1)); + if(Structure.isConformingTo(AStructure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,AStructure);} + } + + CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value); +} +void CAMarrayBase::operator =( const CAMarrayBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),typeValue); + DataP->setReferenceCount(1); + typeValue = CAMType::typeDouble; + referenceFlag = 0; + arrayBaseReferenceCount = 0; + } + else + { + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} + } + + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); +} +ostream& operator <<(ostream& out_stream, const CAMarrayBase& A) +{ + const long* beginPtr = A.Structure.indexBegin.getDataPointer(); + const long* endPtr = A.Structure.indexEnd.getDataPointer(); + const long* stridePtr = A.Structure.indexStride.getDataPointer(); + long i1, i2, i3, i4, i5, i6, i7; + long i; + + int saveWidth=out_stream.width(); + double OutValue; +// +// NEED CONVERSION CHECK +// + switch(A.Structure.dataDimension) + { + case 1 : + for(i1 = *beginPtr; i1 <= *endPtr; i1+= *stridePtr) + { + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1)) << " "; + } + break; + + case 2 : +// +// Use orientation of first quadrant of a cartesian grid. +// + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1,i2)) << " "; + } + out_stream << endl; + } + + break; + + case 3 : + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2,i3)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3)) << " "; + } + out_stream << endl; + } + out_stream << endl << endl; + } + + break; + + case 4 : + + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2,i3,i4)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4)) << " "; + } + out_stream << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + + break; + + case 5 : + + for(i5 = *(beginPtr + 4); i5 <= *(endPtr + 4); i5+= *(stridePtr + 4)) + { + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2,i3,i4,i5)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4,i5)) << " "; + } + out_stream << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + + case 6 : + + for(i6 = *(beginPtr + 5); i6 <= *(endPtr + 5); i6+= *(stridePtr + 5)) + { + for(i5 = *(beginPtr + 4); i5 <= *(endPtr + 4); i5+= *(stridePtr + 4)) + { + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6)) << " "; + } + out_stream << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + break; + + + case 7 : + + for(i7 = *(beginPtr + 6); i7 <= *(endPtr + 6); i7+= *(stridePtr + 6)) + { + for(i6 = *(beginPtr + 5); i6 <= *(endPtr + 5); i6+= *(stridePtr + 5)) + { + for(i5 = *(beginPtr + 4); i5 <= *(endPtr + 4); i5+= *(stridePtr + 4)) + { + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6,i7)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6,i7)) << " "; + } + out_stream << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + out_stream << endl << endl; + } + break; + } + return(out_stream); + +} +istream& operator >>(istream& in_stream, CAMarrayBase& A) +{ + const long* beginPtr = A.Structure.indexBegin.getDataPointer(); + const long* endPtr = A.Structure.indexEnd.getDataPointer(); + const long* stridePtr = A.Structure.indexStride.getDataPointer(); + long i1, i2, i3, i4, i5, i6, i7; + long i; + + if( A.Structure.getFullDataCount() == 0) + {CAMarrayBase::nullOperandError(">>");} +// +// NEED CONVERSION CHECK +// + switch(A.Structure.dataDimension) + { + case 1 : + for(i1 = *beginPtr; i1 <= *endPtr; i1+= *stridePtr) + { + if( !( in_stream >> *((double*)A.getDataPointer(i1)))) + CAMarrayBase::inputSizeError(); + +// out_stream << *((double*)A.getDataPointer(i1)) << " "; + } + break; + + case 2 : +// +// Use orientation of first quadrant of a cartesian grid. +// + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2)))) + CAMarrayBase::inputSizeError(); + +// out_stream << *((double*)A.getDataPointer(i1,i2)) << " "; + }} + + break; + + case 3 : + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2,i3)))) + CAMarrayBase::inputSizeError(); + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3)) << " "; + }}} + + break; + + case 4 : + + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2,i3,i4)))) + CAMarrayBase::inputSizeError(); + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4)) << " "; + }}}} + + break; + + case 5 : + + for(i5 = *(beginPtr + 4); i5 <= *(endPtr + 4); i5+= *(stridePtr + 4)) + { + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2,i3,i4,i5)))) + CAMarrayBase::inputSizeError(); + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4,i5)) << " "; + }}}}} + + case 6 : + + for(i6 = *(beginPtr + 5); i6 <= *(endPtr + 5); i6+= *(stridePtr + 5)) + { + for(i5 = *(beginPtr + 4); i5 <= *(endPtr + 4); i5+= *(stridePtr + 4)) + { + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6)))) + CAMarrayBase::inputSizeError(); + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6)) << " "; + }}}}}} + break; + + + case 7 : + + for(i7 = *(beginPtr + 6); i7 <= *(endPtr + 6); i7+= *(stridePtr + 6)) + { + for(i6 = *(beginPtr + 5); i6 <= *(endPtr + 5); i6+= *(stridePtr + 5)) + { + for(i5 = *(beginPtr + 4); i5 <= *(endPtr + 4); i5+= *(stridePtr + 4)) + { + for(i4 = *(beginPtr + 3); i4 <= *(endPtr + 3); i4+= *(stridePtr + 3)) + { + for(i3 = *(beginPtr + 2); i3 <= *(endPtr + 2); i3+= *(stridePtr + 2)) + { + for(i = ((*(endPtr +1) - *(beginPtr +1))/(*(stridePtr + 1))) + 1; + i >= 1; i--) + { + i2 = *(beginPtr +1) + (i-1)*(*(stridePtr + 1)); + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6,i7)))) + CAMarrayBase::inputSizeError(); + +// out_stream << *((double*)A.getDataPointer(i1,i2,i3,i4,i5,i6,i7)) << " "; + }}}}}}} + break; + } + return(in_stream); + +} + +// +//***************************************************************** +// INITIALIZATION MEMBER_FUNCTIONS +//***************************************************************** +// + +void CAMarrayBase::initialize() +{ + Structure.initialize(); + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + DataP = 0; + typeValue = 0; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +void CAMarrayBase::initialize(int d_type) +{ + Structure.initialize(); + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + DataP = 0; + typeValue = d_type; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +void CAMarrayBase::initialize(const CAMarrayBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + if(A.DataP != 0) + { + A.Structure.initializeMinStructure(Structure); + + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); + } + else + { + DataP = 0; + Structure.initialize(); + } + + typeValue = A.typeValue; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +void CAMarrayBase::initialize(int d_type, const CAMrange& R1, const CAMrange& R2 , + const CAMrange& R3 , const CAMrange&R4 , + const CAMrange& R5 , const CAMrange&R6 , + const CAMrange& R7 ) +{ + Structure.initialize(R1,R2,R3,R4,R5,R6,R7); + + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type); + DataP->setReferenceCount(1); + typeValue = d_type; + referenceFlag = 0; + arrayBaseReferenceCount = 0; +} + +// +//*************************************************************** +// ARRAYOPS.CPP +//*************************************************************** +// +// +//***************************************************************** +// +void CAMarrayBase::initializeReturnArgument(const CAMarrayBase& A) +{ + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); +} +void CAMarrayBase::initializeReturnArgument(const CAMstructureBase& S, int dataT) +{ + S.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(), dataT); + DataP->setReferenceCount(1); +} +void CAMarrayBase::initializeMinDuplicate(const CAMarrayBase& A) +{ + + if(A.DataP == 0) return; + + long i; + long icount = 0; + long dimension = 0; + + for(i = 1; i <= A.Structure.getDimension(); i++) + if(A.Structure[i].getIndexCount() != 1) dimension++; + + + if(dimension == 0) dimension = 1; + Structure.initialize(dimension); + + + for(i = 1; i <= A.Structure.getDimension(); i++) + { + if(A.Structure[i].getIndexCount() != 1) + { + Structure.indexBegin[icount] = 1; + Structure.indexBeginBase[icount] = 1; + Structure.indexEndBase[icount] = A.Structure[i].getIndexCount(); + Structure.indexEnd[icount] = A.Structure[i].getIndexCount(); + Structure.indexStride[icount] = 1; + icount++; + } + } + + if(icount == 0) + { + Structure.indexBegin[icount] = 1; + Structure.indexBeginBase[icount] = 1; + Structure.indexEndBase[icount] = 1; + Structure.indexEnd[icount] = 1; + Structure.indexStride[icount] = 1; + } + DataP = new CAMdataHandler(Structure.getFullDataCount(), A.typeValue); + DataP->setReferenceCount(1); +// +// copy over data +// + *this = A; +} +// +//***************************************************************** +// Operators +//***************************************************************** +// +CAMarrayBase CAMarrayBase::operator-() const +{ +// +// NEED CONVERSION CHECK +// + CAMarrayBase S; + S.initializeReturnArgument(*this); + + CAMbinaryEngine::doubleAequalToMinusB(S.Structure, *S.DataP, Structure, *DataP); + S.setTemporaryFlag(); + return S; +} + +CAMarrayBase CAMarrayBase::operator+(const CAMarrayBase& A) const +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMarrayBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMarrayBase CAMarrayBase::operator-(const CAMarrayBase& A) const +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMarrayBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAminusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMarrayBase CAMarrayBase::operator*(const CAMarrayBase& A) const +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMarrayBase S; + S.initializeReturnArgument(A); + + CAMbinaryEngine::doubleCequalAtimesB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMarrayBase CAMarrayBase::operator/(const CAMarrayBase& A) const +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMarrayBase S; + S.initializeReturnArgument(A); + + CAMbinaryEngine::doubleCequalAdivideB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +// +//***************************************************************** +// op = Operators +//***************************************************************** +// + +void CAMarrayBase::operator+=(const CAMarrayBase& A) +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAplusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMarrayBase::operator-=(const CAMarrayBase& A) +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAminusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMarrayBase::operator*=(const CAMarrayBase& A) +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAtimesEqualB(Structure, *DataP, A.Structure, *A.DataP); +} + +void CAMarrayBase::operator/=(const CAMarrayBase& A) +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAdivideEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +// +//***************************************************************** +// Operations with Scalers +//***************************************************************** +// +CAMarrayBase CAMarrayBase::operator +(const double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isConformingTo(AStructure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,AStructure);} + + CAMarrayBase S(*this); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} +CAMarrayBase operator +(const double value, const CAMarrayBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase BStructure(_(1,1)); + if(A.Structure.isConformingTo(BStructure) != 1) + {CAMarrayBase::nonConformingMessage(A.Structure,BStructure);} + + CAMarrayBase S(A); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +CAMarrayBase CAMarrayBase::operator -(const double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isConformingTo(AStructure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,AStructure);} + + CAMarrayBase S(*this); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +CAMarrayBase operator -(const double value, const CAMarrayBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase BStructure(_(1,1)); + if(A.Structure.isConformingTo(BStructure) != 1) + {CAMarrayBase::nonConformingMessage(A.Structure,BStructure);} + + CAMarrayBase S(A); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +void CAMarrayBase::operator +=(const double value) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isConformingTo(AStructure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,AStructure);} + + CAMbinaryEngine::doubleAplusEqualAlpha(Structure, *(DataP), value); +} + +void CAMarrayBase::operator -=(const double value) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isConformingTo(AStructure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,AStructure);} + + CAMbinaryEngine::doubleAminusEqualAlpha(Structure, *(DataP), value); +} + +CAMarrayBase CAMarrayBase::operator*(double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMarrayBase S(*this); + CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMarrayBase operator *(double value, const CAMarrayBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMarrayBase S(A); + CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMarrayBase CAMarrayBase::operator /(double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMarrayBase S(*this); + CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMarrayBase operator /(double value, const CAMarrayBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMarrayBase S(A); + CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +void CAMarrayBase::operator *=(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMbinaryEngine::doubleAtimesEqualAlpha(Structure, *DataP, value); +} + +void CAMarrayBase::operator /=(double value) +{ + CAMbinaryEngine::doubleAdivideEqualAlpha(Structure, *DataP, value); +} + + + +void CAMarrayBase::setToValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value); +} + +CAMarrayBase CAMarrayBase::plusValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMarrayBase S(*this); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMarrayBase CAMarrayBase::minusValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMarrayBase S(*this); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +// +//***************************************************************** +// Temporary and Reference Utilities +//***************************************************************** +// +void CAMarrayBase::exchangeContentsWith(CAMarrayBase& B) +{ +// +// This routine exchanges the contents of *this with B. +// The routine is typically used with *this input as +// a null object and B a temporary object (i.e. the result +// of an operator or function which returns B with the +// temporary flag set). In such a case, the contents of +// B are captured by *this --- resulting in a transfer of the +// results without invoking a data copy. +// +// + CAMstructureBase S_temp(Structure); + CAMdataHandler* DataP_temp = DataP; + int typeValue_temp = typeValue; + int referenceFlag_temp = referenceFlag; + long arrayBaseReferenceCount_temp = arrayBaseReferenceCount; + + Structure.initialize(B.Structure); + DataP = B.DataP; + typeValue = B.typeValue; + referenceFlag = B.referenceFlag; + arrayBaseReferenceCount = B.arrayBaseReferenceCount; +// + B.Structure.initialize(S_temp); + B.DataP = DataP_temp; + B.typeValue = typeValue_temp; + B.referenceFlag = referenceFlag_temp; + B.arrayBaseReferenceCount = arrayBaseReferenceCount_temp; +} + +void CAMarrayBase::initializeReferenceDuplicate(const CAMarrayBase& B) +{ +// +// This routine initializes *this with the contents of B and +// and sets the *this reference flag. This results in a +// class instance whose data is that associated with B. +// +// Typically this routine is used in a container class which +// contains arrays --- and one wants to have sub-array access +// for the contained class which is based upon the sub-array +// access of the array class. +// + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + Structure.initialize(B.Structure); + DataP = B.DataP; + DataP->incrementReferenceCount(); //One Reference for local copy + DataP->incrementReferenceCount(); //One Reference for compiler copy + typeValue = B.typeValue; + referenceFlag = 1; + arrayBaseReferenceCount = 0; +} +// +//***************************************************************** +// CONVERSIONS +//***************************************************************** +// +CAMmatrixBase CAMarrayBase::asMatrix() const +{ + CAMmatrixBase S; + if(DataP == 0) return S; + + CAMrange R1; CAMrange R2; + long i; + long dimension = 0; + + for(i = 1; i <= getDimension(); i++) + { + if(Structure[i].getIndexCount() != 1) + { + dimension++; + if(dimension == 1) + R1.initialize(Structure[i].getIndexBase(),Structure[i].getIndexBound()); + if(dimension == 2) + R2.initialize(Structure[i].getIndexBase(),Structure[i].getIndexBound()); + } + } + switch (dimension) + { + case 0 : + R1.initialize(Structure[1].getIndexBase(),Structure[1].getIndexBound()); + R2.initialize(Structure[1].getIndexBaseBase(),Structure[1].getIndexBaseBase()); + break; + + case 1 : + R2.initialize(Structure[1].getIndexBaseBase(),Structure[1].getIndexBaseBase()); + break; + + case 2 : + break; + default : + CAMarrayBase::objectConversionError(Structure); + } +// +// + S.initialize(CAMType::typeDouble, R1,R2); + CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP); +// +// + S.setTemporaryFlag(); + return S; +} +CAMvectorBase CAMarrayBase::asVector() const +{ + CAMvectorBase S; + if(DataP == 0) return S; + + CAMrange R1; + long i; + long dimension = 0; + + for(i = 1; i <= getDimension(); i++) + { + if(Structure[i].getIndexCount() != 1) + { + dimension++; + if(dimension == 1) + R1.initialize(Structure[i].getIndexBase(),Structure[i].getIndexBound()); + } + } + switch (dimension) + { + case 0 : + R1.initialize(Structure[1].getIndexBase(),Structure[1].getIndexBound()); + break; + + case 1 : + break; + default : + CAMarrayBase::objectConversionError(Structure); + + } +// +// + S.initialize(CAMType::typeDouble, R1); + CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP); +// +// + S.setTemporaryFlag(); + return S; +} +// +//***************************************************************** +// DIMENSION SELECTION +//***************************************************************** +// +CAMstructureBase& CAMarrayBase::operator[](long i) +{ + if((i < 0)||(i > Structure.dataDimension)) + {CAMstructureBase::illegalDimension(i, Structure.dataDimension);} + + Structure.exchangeReferenceIndex(i); + + return Structure; +} + +const CAMstructureBase& CAMarrayBase::operator[](long i) const +{ + if((i < 0)||(i > Structure.dataDimension)) + {CAMstructureBase::illegalDimension(i, Structure.dataDimension);} + + Structure.exchangeReferenceIndex(i); + + return Structure; +} +// +//******************************************************************************** +// Array Helper Functions +//******************************************************************************** +// +void* CAMarrayBase::getDataPointer(long i1, long i2, long i3, long i4, +long i5, long i6, long i7) const +{ + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + long i[7]; + + i[0] = i1; i[1] = i2; i[2] = i3; i[3] = i4; + i[4] = i5; i[5] = i6; i[6] = i7; +// +// NEED CONVERSION CHECK +// + double* dataPtr = (double*)(DataP->dataPointer); + + long offset; + offset = (i[Structure.dataDimension - 1] + - *(beginPtr + (Structure.dataDimension - 1))); + for(long j = Structure.dataDimension - 2; j >= 0; j--) + { + offset = (i[j] - *(beginPtr + j)) + + offset*((*(endPtr + j) - *(beginPtr + j)) + 1); + } + + return (void*)(dataPtr + offset); +} +// +//******************************************************************************** +// Reference Counting Functions +//******************************************************************************** +// + +void CAMarrayBase::incrementReferenceCount() +{ + if(arrayBaseReferenceCount == 0) CAMarrayBase::referenceCountError(); + arrayBaseReferenceCount++; +} + +void CAMarrayBase::referenceCountError() +{ +cerr << " Cannot Use Reference Counting on Objects New\'d by the Compiler " << endl; +CAMmvaExit(); +} +// +//***************************************************************** +// MEMBER_FUNCTIONS +//***************************************************************** +// + +void CAMarrayBase::indexCheck(const CAMstructureBase &S, long i1) +{ + if(S.dataDimension != 1) + { + cerr << " Error : Incorrect Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << " --- Dimension Used = "<< 1 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMarrayBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } +} + +void CAMarrayBase::indexCheck(const CAMstructureBase &S, long i1, long i2) +{ + if(S.dataDimension != 2) + { + cerr << " Error : Incorrect Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 2 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMarrayBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMarrayBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } +} + +void CAMarrayBase::indexCheck(const CAMstructureBase &S, long i1, long i2, long i3) +{ + if(S.dataDimension != 3) + { + cerr << " Error : Incorrect Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 3 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMarrayBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMarrayBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } + if((i3 < *(indexBeginP +2))||(i3 > *(indexEndP+2))) + { + CAMarrayBase::indexErrorMessage(3, *(indexBeginP+2), *(indexEndP+2), i3); + } +} + +void CAMarrayBase::indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4) +{ + if(S.dataDimension != 4) + { + cerr << " Error : Incorrect Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 4 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMarrayBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMarrayBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } + if((i3 < *(indexBeginP +2))||(i3 > *(indexEndP+2))) + { + CAMarrayBase::indexErrorMessage(3, *(indexBeginP+2), *(indexEndP+2), i3); + } + if((i4 < *(indexBeginP +3))||(i4 > *(indexEndP+3))) + { + CAMarrayBase::indexErrorMessage(4, *(indexBeginP+3), *(indexEndP+3), i4); + } + +} + +void CAMarrayBase::indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4, long i5) +{ + if(S.dataDimension != 5) + { + cerr << " Error : Incorrect Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 5 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMarrayBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMarrayBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } + if((i3 < *(indexBeginP +2))||(i3 > *(indexEndP+2))) + { + CAMarrayBase::indexErrorMessage(3, *(indexBeginP+2), *(indexEndP+2), i3); + } + if((i4 < *(indexBeginP +3))||(i4 > *(indexEndP+3))) + { + CAMarrayBase::indexErrorMessage(4, *(indexBeginP+3), *(indexEndP+3), i4); + } + if((i5 < *(indexBeginP +4))||(i5 > *(indexEndP+4))) + { + CAMarrayBase::indexErrorMessage(5, *(indexBeginP+4), *(indexEndP+4), i5); + } +} + +void CAMarrayBase::indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4, long i5, long i6) +{ + if(S.dataDimension != 6) + { + cerr << " Error : Incorrect Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 6 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMarrayBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMarrayBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } + if((i3 < *(indexBeginP +2))||(i3 > *(indexEndP+2))) + { + CAMarrayBase::indexErrorMessage(3, *(indexBeginP+2), *(indexEndP+2), i3); + } + if((i4 < *(indexBeginP +3))||(i4 > *(indexEndP+3))) + { + CAMarrayBase::indexErrorMessage(4, *(indexBeginP+3), *(indexEndP+3), i4); + } + if((i5 < *(indexBeginP +4))||(i5 > *(indexEndP+4))) + { + CAMarrayBase::indexErrorMessage(5, *(indexBeginP+4), *(indexEndP+4), i5); + } + if((i6 < *(indexBeginP +5))||(i6 > *(indexEndP+5))) + { + CAMarrayBase::indexErrorMessage(6, *(indexBeginP+5), *(indexEndP+5), i6); + } +} + +void CAMarrayBase::indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4, long i5, long i6, long i7) +{ + if(S.dataDimension != 7) + { + cerr << " Error : Incorrect Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 7 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMarrayBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMarrayBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } + if((i3 < *(indexBeginP +2))||(i3 > *(indexEndP+2))) + { + CAMarrayBase::indexErrorMessage(3, *(indexBeginP+2), *(indexEndP+2), i3); + } + if((i4 < *(indexBeginP +3))||(i4 > *(indexEndP+3))) + { + CAMarrayBase::indexErrorMessage(4, *(indexBeginP+3), *(indexEndP+3), i4); + } + if((i5 < *(indexBeginP +4))||(i5 > *(indexEndP+4))) + { + CAMarrayBase::indexErrorMessage(5, *(indexBeginP+4), *(indexEndP+4), i5); + } + if((i6 < *(indexBeginP +5))||(i6 > *(indexEndP+5))) + { + CAMarrayBase::indexErrorMessage(6, *(indexBeginP+5), *(indexEndP+5), i6); + } + if((i7 < *(indexBeginP +6))||(i7 > *(indexEndP+6))) + { + CAMarrayBase::indexErrorMessage(7, *(indexBeginP+6), *(indexEndP+6), i7); + } +} +void CAMarrayBase::indexErrorMessage(long indexDimension, long base, long bound, long index) +{ + cerr << " Error : Index " << indexDimension << " Out of Range " << endl; + + cerr << " Current Index Range :(" << base << ", " << bound << ")" << endl; + cerr << " Index Used : " << index << endl; + CAMmvaExit(); +} +void CAMarrayBase::nonConformingMessage(const CAMstructureBase& A, const CAMstructureBase& B) +{ + long i; + cerr << endl; + cerr << "Error : Object Dimensions not Compatable with Operation " << endl << endl; + cerr << "Left Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + cerr << "Right Operand Dimensions : "; + cerr << B[1].getIndexCount(); + for(i = 2; i <= B.dataDimension; i++) + cerr << " x " << B[i].getIndexCount(); + cerr << endl << endl; + CAMmvaExit(); +} +void CAMarrayBase::doubleConversionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << "Dimensions not Compatable with Conversion to Double " << endl << endl; + cerr << "Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} + +void CAMarrayBase::objectConversionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << " Dimensions not Compatable with Conversion Operator " << endl << endl; + cerr << "Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +void CAMarrayBase::nullOperandError() +{ + cerr << endl; + cerr << " Error : Null Object Used As Operand " << endl; + CAMmvaExit(); +} +void CAMarrayBase::nullOperandError(char* Operation) +{ + cerr << endl; + cerr << " Error : Null Object Used As Operand With "<< Operation << endl; + CAMmvaExit(); +} +void CAMarrayBase::inputSizeError() +{ + cerr << endl; + cerr << " Input error : Insufficient # of data elements in input stream " << endl; + CAMmvaExit(); +} +// +//***************************************************************** +// CPP File End +//***************************************************************** +// + + + + + + + + + + + + + diff --git a/src/matrix/arraybse.h b/src/matrix/arraybse.h new file mode 100755 index 0000000..d5c06e2 --- /dev/null +++ b/src/matrix/arraybse.h @@ -0,0 +1,205 @@ +// +//****************************************************************************** +// ARRAYBSE.H +//****************************************************************************** +// + +#include +#include +#include "strctbse.h" +#include "datahndl.h" +#include "access.h" +#include "mvaexit.h" +#include "camtype.h" +#include "typehndl.h" + +// +// +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Tue Apr 16 11:30:42 1996 +// +//******************************************************************************** +// +#ifndef __NO_COMPLEX__ +#define __NO_COMPLEX__ +#endif +// +// +#include "mvaimpexp.h" // C +// +// +#ifndef _CAMMATRIXBASE_ +class CAMmatrixBase; +#endif +#ifndef _CAMVECTORBASE_ +class CAMvectorBase; +#endif +// +// +// + +#ifndef _CAMARRAYBASE_ +#define _CAMARRAYBASE_ + + +class __IMPEXP__ CAMarrayBase +{ + +public : + + CAMstructureBase Structure; + CAMdataHandler* DataP; + int typeValue; + int referenceFlag; + long arrayBaseReferenceCount; + +public : + +// +// Constructors +// + CAMarrayBase(); + CAMarrayBase( const CAMarrayBase& A); + CAMarrayBase(int d_type); + CAMarrayBase(int d_type, const CAMrange& R1, const CAMrange& R2 = CAMnullRange, + const CAMrange& R3 = CAMnullRange, const CAMrange&R4 = CAMnullRange, + const CAMrange& R5 = CAMnullRange, const CAMrange&R6 = CAMnullRange, + const CAMrange& R7 = CAMnullRange); +// +// Destructor +// + ~CAMarrayBase(); +// +// Assignment +// + void operator = (double value); + void operator = (const CAMarrayBase& A); +// +// Output +// + __IMPEXP__ friend ostream& operator <<(ostream& out_stream, const CAMarrayBase& A); +// +// Input +// + __IMPEXP__ friend istream& operator >>(istream& in_stream, CAMarrayBase& A); +// +// Initialization Functions +// + void initialize(); + void initialize(const CAMarrayBase& A); + void initialize(int d_type); + void initialize(int d_type, const CAMrange& R1, const CAMrange& R2 = CAMnullRange, + const CAMrange& R3 = CAMnullRange, const CAMrange&R4 = CAMnullRange, + const CAMrange& R5 = CAMnullRange, const CAMrange&R6 = CAMnullRange, + const CAMrange& R7 = CAMnullRange); +// +// Unary and Binary Operations +// + CAMarrayBase operator-() const; + CAMarrayBase operator+(const CAMarrayBase& A) const; + CAMarrayBase operator-(const CAMarrayBase& A) const; + CAMarrayBase operator*(const CAMarrayBase& A) const; + CAMarrayBase operator/(const CAMarrayBase& A) const; + void operator+=(const CAMarrayBase& A); + void operator-=(const CAMarrayBase& A); + void operator*=(const CAMarrayBase& A); + void operator/=(const CAMarrayBase& A); +// +// Scaler Operations +// + CAMarrayBase operator +(const double value) const; + __IMPEXP__ friend CAMarrayBase operator +(const double value, const CAMarrayBase& A); + CAMarrayBase operator -(const double value) const; + __IMPEXP__ friend CAMarrayBase operator -(const double value, const CAMarrayBase& A); + void operator +=(const double value); + void operator -=(const double value); + CAMarrayBase operator *(double value) const; + __IMPEXP__ friend CAMarrayBase operator *(double value, const CAMarrayBase& A); + CAMarrayBase operator /(double value) const; + __IMPEXP__ friend CAMarrayBase operator /(double value, const CAMarrayBase& A); + void operator *=(double value); + void operator /=(double value); +// +// Additional Scalar Functions +// + void setToValue(double value); + CAMarrayBase plusValue(double value); + CAMarrayBase minusValue(double value); +// +// Helper Functions +// + void setTemporaryFlag(){DataP->setTemporaryFlag();}; + void initializeReturnArgument(const CAMstructureBase& S, int dataT); + void initializeReturnArgument(const CAMarrayBase& A); + void initializeMinDuplicate(const CAMarrayBase& A); + void* getDataPointer() const {return DataP->getDataPointer();}; + void* getDataPointer(long i1, long i2 = 0, long i3 = 0, long i4 = 0, + long i5 =0, long i6 = 0, long i7 = 0) const; + CAMmatrixBase asMatrix() const; + CAMvectorBase asVector() const; +// +// Structure Functions +// + const CAMstructureBase& operator[](long i) const; + CAMstructureBase& operator[](long i); + void setAllIndexBase(long i){Structure.setAllIndexBase(i);}; + long getDimension() const {return Structure.getDimension();}; +// +// Reference Counting +// + void incrementReferenceCount(); + void decrementReferenceCount(){arrayBaseReferenceCount--;}; + int getReferenceCount() const {return arrayBaseReferenceCount;}; + void setReferenceCount(int refValue){arrayBaseReferenceCount = refValue;}; + static void referenceCountError(); +// +// Error Handling Routines +// + static void indexCheck(const CAMstructureBase &S, long i1); + static void indexCheck(const CAMstructureBase &S, long i1, long i2); + static void indexCheck(const CAMstructureBase &S, long i1, long i2, long i3); + static void indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4); + static void indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4, long i5); + static void indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4, long i5, long i6); + static void indexCheck(const CAMstructureBase &S, long i1, long i2, long i3, long i4, long i5, long i6, long i7); + static void indexErrorMessage(long indexDimension, long base, long bound, long index); + static void nonConformingMessage(const CAMstructureBase &A,const CAMstructureBase &B); + static void doubleConversionError(const CAMstructureBase& A); + static void objectConversionError(const CAMstructureBase& A); + static void nullOperandError(); + static void nullOperandError(char* Operation); + static void inputSizeError(); +// +// Utility Functions +// + double max() const; + double min() const; + double maxAbs() const; + double minAbs() const; + double infNorm() const; + double pNorm(int p) const; + double pNorm(long p) const; + double pNorm(float p) const; + double pNorm(double p) const; +// +// temporary and reference utility functions +// + void exchangeContentsWith(CAMarrayBase& B); + void initializeReferenceDuplicate(const CAMarrayBase& B); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + diff --git a/src/matrix/arraygph.cpp b/src/matrix/arraygph.cpp new file mode 100755 index 0000000..c6d52ef --- /dev/null +++ b/src/matrix/arraygph.cpp @@ -0,0 +1,530 @@ +#include "arraybse.h" +// +//****************************************************************************** +// ARRAYGPH.CPP +//****************************************************************************** +// +// BINDINGS TO THE UC GRAHPICS CLASSES +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Tue Sep 26 14:40:00 1995 +// +//******************************************************************************** +// + +void CAMarrayBase::plot() const +{ +// +// Need Conversion Check +// + long dimension; + long M,N; + + const CAMarrayBase* InputPtr; + CAMarrayBase A; + + double* AdataPtr; double* BdataPtr; + + long j; int autoFlag; + double x_min, x_max, y_min, y_max; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + InputPtr = &A; + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + InputPtr = this; + } + + switch (dimension) + { + case 1 : + CAMgraphics::plot(AdataPtr,M); + + break; + + case 2 : + autoFlag = CAMgraphics::getAutoScaleFlag(); + x_min = 1; + x_max = M; + y_min = InputPtr->min(); + y_max = InputPtr->max(); + CAMgraphics::axis(x_min,x_max,y_min,y_max); + for(j = 1; j <= N; j++) + { + BdataPtr = AdataPtr + (j-1)*M; + CAMgraphics::plot(BdataPtr,M); + } + CAMgraphics::axis(autoFlag); + + break; + default : + CAMarrayBase::plotDimensionError(A.Structure); + } + +} + +void CAMarrayBase::plot(int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + if(p_arg < 32) + { CAMgraphics::setPlotStyle(p_arg);} + else + { CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(CAMgraphics::POINTS); + } + + this->plot(); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} +void CAMarrayBase::plot(int p_style, int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(p_style); + + this->plot(); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} +void CAMarrayBase::plot(const CAMarrayBase& Ordinates) const +{ +// +// Need Conversion Check +// + long dimension; + long M,N; + + CAMarrayBase A; + const CAMarrayBase* InputPtr; + double* AdataPtr; double* BdataPtr; + + long j; int autoFlag; + double x_min, x_max, y_min, y_max; + + CAMarrayBase O; + double* OdataPtr; + long Odimension; + long Ocount; +// + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + InputPtr = &A; + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + InputPtr = this; + } + + if(Ordinates.Structure.isSubset() == 1) + { + O.initializeMinDuplicate(Ordinates); + Odimension = O.getDimension(); + OdataPtr = (double*)O.getDataPointer(); + Ocount = O[1].getIndexCount(); + } + else + { + Odimension = Ordinates.getDimension(); + OdataPtr = (double*)Ordinates.getDataPointer(); + Ocount = Ordinates[1].getIndexCount(); + } + + if(Odimension != 1) + {CAMarrayBase::ordinateError(Ordinates.Structure);} + + if(M != Ocount) + {CAMarrayBase::ordinateError(Ordinates.Structure);} + + switch (dimension) + { + case 1 : + CAMgraphics::plot(OdataPtr,AdataPtr,M); + + break; + + case 2 : + + autoFlag = CAMgraphics::getAutoScaleFlag(); + x_min = *OdataPtr; + x_max = *(OdataPtr +(M-1)); + y_min = InputPtr->min(); + y_max = InputPtr->max(); + CAMgraphics::axis(x_min,x_max,y_min,y_max); + for(j = 1; j <= N; j++) + { + BdataPtr = AdataPtr + (j-1)*M; + CAMgraphics::plot(OdataPtr, BdataPtr,M); + } + CAMgraphics::axis(autoFlag); + + break; + default : + CAMarrayBase::plotDimensionError(A.Structure); + } + +} + +void CAMarrayBase::plot(const CAMarrayBase& Ordinates, int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + if(p_arg < 32) + { CAMgraphics::setPlotStyle(p_arg);} + else + { CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(CAMgraphics::POINTS); + } + + this->plot(Ordinates); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} + +void CAMarrayBase::plot(const CAMarrayBase& Ordinates, int p_arg, int p_style) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(p_style); + + this->plot(Ordinates); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} + +void CAMarrayBase::contour() const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::contour(AdataPtr,M,N); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMarrayBase::plotDimensionError(A.Structure);} + +} + +void CAMarrayBase::contour(int nContour) const +{ + CAMgraphics::setContourLevel(nContour); + this->contour(); +} + +void CAMarrayBase::contour(long nContour) const +{ + CAMgraphics::setContourLevel(nContour); + this->contour(); +} +void CAMarrayBase::contour(double increment) const +{ + CAMgraphics::setContourLevel(increment); + this->contour(); +} + +void CAMarrayBase::contour(double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(low_value, high_value); + this->contour(); +} + +void CAMarrayBase::contour(long nContour, double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(nContour, low_value, high_value); + this->contour(); +} + +void CAMarrayBase::contour(int nContour, double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(nContour, low_value, high_value); + this->contour(); +} + +void CAMarrayBase::contour(double increment, double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(increment, low_value, high_value); + this->contour(); +} + +void CAMarrayBase::contour(const CAMarrayBase& contourValues) const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + CAMarrayBase CV; + double* CVdataPtr; + long CVdimension; + long CVcount; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(contourValues.Structure.isSubset() == 1) + { + CV.initializeMinDuplicate(contourValues); + CVdimension = CV.getDimension(); + CVdataPtr = (double*)CV.getDataPointer(); + CVcount = CV[1].getIndexCount(); + } + else + { + CVdimension = contourValues.getDimension(); + CVdataPtr = (double*)contourValues.getDataPointer(); + CVcount = contourValues[1].getIndexCount(); + } + + + if(CVdimension != 1) + {CAMarrayBase::ordinateError(contourValues.Structure);} + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::contour(AdataPtr,M,N,CVdataPtr,CVcount); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMarrayBase::plotDimensionError(A.Structure);} + +} + +void CAMarrayBase::surface() const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::surface(AdataPtr,M,N); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMarrayBase::plotDimensionError(A.Structure);} +} + +void CAMarrayBase::surface(const CAMarrayBase& x, const CAMarrayBase& y) const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + CAMarrayBase XC; + double* XCdataPtr; + long XCdimension; + long XCcount; + + CAMarrayBase YC; + double* YCdataPtr; + long YCdimension; + long YCcount; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(x.Structure.isSubset() == 1) + { + XC.initializeMinDuplicate(x); + XCdimension = x.getDimension(); + XCdataPtr = (double*)x.getDataPointer(); + XCcount = x[1].getIndexCount(); + } + else + { + XCdimension = x.getDimension(); + XCdataPtr = (double*)x.getDataPointer(); + XCcount = x[1].getIndexCount(); + } + + if(y.Structure.isSubset() == 1) + { + YC.initializeMinDuplicate(y); + YCdimension = y.getDimension(); + YCdataPtr = (double*)y.getDataPointer(); + YCcount = y[1].getIndexCount(); + } + else + { + YCdimension = y.getDimension(); + YCdataPtr = (double*)y.getDataPointer(); + YCcount = y[1].getIndexCount(); + } + + if(XCdimension != 1) + {CAMarrayBase::ordinateError(x.Structure);} + + if(YCdimension != 1) + {CAMarrayBase::ordinateError(y.Structure);} + + if(M != XCcount) + {CAMarrayBase::ordinateError(x.Structure);} + + if(N != YCcount) + {CAMarrayBase::ordinateError(y.Structure);} + + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::surface(AdataPtr,M, N, XCdataPtr, YCdataPtr); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMarrayBase::plotDimensionError(A.Structure);} + +} + +void CAMarrayBase::ordinateError(const CAMstructureBase & A) +{ + long i; + cerr << endl; + cerr << " Ordinates in Plot Command Incorrectly Specified " << endl << endl; + cerr << " Error in Number of Ordinates or Ordinate Array Dimension " << endl; + cerr << " Ordinates Size : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +void CAMarrayBase::plotDimensionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << "Error : Object Dimensions not Compatable with Plot Operation " << endl << endl; + cerr << " Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + diff --git a/src/matrix/arrayops.cpp b/src/matrix/arrayops.cpp new file mode 100755 index 0000000..72c26ba --- /dev/null +++ b/src/matrix/arrayops.cpp @@ -0,0 +1,39 @@ +#include "arraybse.h" +#include "bnengine.h" +// +//****************************************************************************** +// ARRAYOPS.CPP +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson +// +// Mon Sep 11 12:49:20 1995 +// +void CAMarrayBase::initializeReturnArgument(const CAMarrayBase& A) +{ + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); +} +// +//******************************************************************************** +// Operator + +//******************************************************************************** +// +CAMarrayBase CAMarrayBase::operator+(const CAMarrayBase& A) const +{ + if(Structure.isConformingTo(A.Structure) != 1) + {CAMarrayBase::nonConformingMessage(Structure,A.Structure);} + + CAMarrayBase S; + S.initializeReturnArgument(A); + + CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} diff --git a/src/matrix/arrayutl.cpp b/src/matrix/arrayutl.cpp new file mode 100755 index 0000000..0860695 --- /dev/null +++ b/src/matrix/arrayutl.cpp @@ -0,0 +1,181 @@ +#include "arraybse.h" +#include "bnengine.h" +// +//******************************************************************************** +// UTILITY MEMBER_FUNCTIONS +//******************************************************************************** +// +// +// Routines return double. When adding multiple data types, I'll +// need to promote the utilities to the derived classes so that +// they can return the appropriate type. +// +double CAMarrayBase::max() const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxValue(AdataP, n, value); + return value; +} + +double CAMarrayBase::min() const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMinValue(AdataP, n, value); + return value; +} + +double CAMarrayBase::maxAbs() const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxAbsValue(AdataP, n, value); + return value; +} + +double CAMarrayBase::minAbs() const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMinAbsValue(AdataP, n, value); + return value; +} + + +double CAMarrayBase::infNorm() const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxAbsValue(AdataP, n, value); + return value; +} + +double CAMarrayBase::pNorm(double p) const +{ +// +// Need Conversion Check +// + CAMarrayBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doublepNorm(AdataP, n, p, value); + return value; +} + +double CAMarrayBase::pNorm(int p) const {return pNorm(double(p));} +double CAMarrayBase::pNorm(long p) const {return pNorm(double(p));} +double CAMarrayBase::pNorm(float p) const {return pNorm(double(p));} + +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + + + diff --git a/src/matrix/bnengine.h b/src/matrix/bnengine.h new file mode 100755 index 0000000..74e68d8 --- /dev/null +++ b/src/matrix/bnengine.h @@ -0,0 +1,84 @@ +// +//****************************************************************************** +// BNENGINE.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Sat Feb 03 18:11:18 1996 +// +//******************************************************************************** +// + +#include +#include "strctbse.h" +#include "datahndl.h" + + +#ifndef __CAMBINARYENGINE__ +#define __CAMBINARYENGINE__ + +#include "mvaimpexp.h" // C + +class __IMPEXP__ CAMbinaryEngine +{ + +public : + +// +// +// + static void doubleAequalToB(CAMstructureBase &Astructure, CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata); + static void doubleAequalToMinusB(CAMstructureBase &Astructure, CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata); + static void doubleAplusEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata); + static void doubleAminusEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata); + static void doubleAtimesEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata); + static void doubleAdivideEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata); + static void doubleCequalAplusB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, + CAMstructureBase &Cstructure, CAMdataHandler &Cdata); + static void doubleCequalAminusB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, + CAMstructureBase &Cstructure, CAMdataHandler &Cdata); + static void doubleCequalAtimesB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, + CAMstructureBase &Cstructure, CAMdataHandler &Cdata); + static void doubleCequalAdivideB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, + const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, + CAMstructureBase &Cstructure, CAMdataHandler &Cdata); + static void doubleAequalToAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, + double alpha); + static void doubleAplusEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, + double alpha); + static void doubleAminusEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, + double alpha); + static void doubleAtimesEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, + double alpha); + static void doubleAdivideEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, + double alpha); + static void doubleMaxValue(double* data, long n, double& maxValue); + static void doubleMinValue(double* data, long n, double& minValue); + static void doubleMaxAbsValue(double* data, long n, double& maxAbsValue); + static void doubleMinAbsValue(double* data, long n, double& minAbsValue); + static void doublepNorm(double* data, long n, double p, double& pNormValue); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + diff --git a/src/matrix/camblas/CVS/Entries b/src/matrix/camblas/CVS/Entries new file mode 100644 index 0000000..8017308 --- /dev/null +++ b/src/matrix/camblas/CVS/Entries @@ -0,0 +1,29 @@ +/Jamfile/1.3/Tue Dec 9 00:59:55 2003// +/blas.cpp/1.1/Tue Mar 25 20:01:14 2003// +/blas.h/1.1/Tue Mar 25 20:01:16 2003// +/blasimpexp.h/1.1/Tue Mar 25 20:01:16 2003// +/cblasimpexp.h/1.1/Tue Mar 25 20:01:18 2003// +/cinterface.pdf/1.1/Tue Mar 25 20:01:19 2003// +/dasum.c/1.1/Tue Mar 25 20:01:27 2003// +/daxpy.c/1.1/Tue Mar 25 20:01:28 2003// +/dcopy.c/1.1/Tue Mar 25 20:01:29 2003// +/ddot.c/1.1/Tue Mar 25 20:01:29 2003// +/dgemm.c/1.1/Tue Mar 25 20:01:29 2003// +/dgemv.c/1.1/Tue Mar 25 20:01:29 2003// +/dger.c/1.1/Tue Mar 25 20:01:29 2003// +/dnrm2.c/1.1/Tue Mar 25 20:01:29 2003// +/drot.c/1.1/Tue Mar 25 20:01:29 2003// +/dscal.c/1.1/Tue Mar 25 20:01:29 2003// +/dswap.c/1.1/Tue Mar 25 20:01:29 2003// +/dsymv.c/1.1/Tue Mar 25 20:01:29 2003// +/dsyr2.c/1.1/Tue Mar 25 20:01:30 2003// +/dsyr2k.c/1.1/Tue Mar 25 20:01:31 2003// +/dtrmm.c/1.1/Tue Mar 25 20:01:31 2003// +/dtrmv.c/1.1/Tue Mar 25 20:01:31 2003// +/f2c.h/1.1/Tue Mar 25 20:01:31 2003// +/ilaenv.c/1.1/Tue Mar 25 20:01:32 2003// +/lsame.c/1.1/Tue Mar 25 20:01:33 2003// +/s_cmp.c/1.1/Tue Mar 25 20:01:37 2003// +/s_copy.c/1.1/Tue Mar 25 20:01:38 2003// +/xerbla.c/1.1/Tue Mar 25 20:01:38 2003// +D diff --git a/src/matrix/camblas/CVS/Repository b/src/matrix/camblas/CVS/Repository new file mode 100644 index 0000000..c0d3b82 --- /dev/null +++ b/src/matrix/camblas/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/matrix/camblas diff --git a/src/matrix/camblas/CVS/Root b/src/matrix/camblas/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/matrix/camblas/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/matrix/camblas/Jamfile b/src/matrix/camblas/Jamfile new file mode 100644 index 0000000..d56a915 --- /dev/null +++ b/src/matrix/camblas/Jamfile @@ -0,0 +1,15 @@ +########################################### +# Jamfile for the Camblas routines +# +# Author: xb70 (Troy B. Jones) +# Revision: 6/29/2003 +########################################### + +# Location of this Jamfile +SubDir OPENSESSAME_ROOT src matrix camblas ; + +# Compile the following sources to objects +Objects dasum.c daxpy.c dcopy.c ddot.c dgemm.c dgemv.c dger.c dnrm2.c drot.c dscal.c dswap.c dsymv.c dsyr2.c dsyr2k.c dtrmm.c dtrmv.c ilaenv.c lsame.c s_cmp.c s_copy.c xerbla.c ; + + + diff --git a/src/matrix/camblas/blas.cpp b/src/matrix/camblas/blas.cpp new file mode 100644 index 0000000..0873c2b --- /dev/null +++ b/src/matrix/camblas/blas.cpp @@ -0,0 +1,138 @@ +#include "blas.h" +// +// C++ implementations of level 1 Blas --- selectively replaced by +// other implementations at link time +// +int icopy_(long* n, int* ix, long* incx, int* iy, long* incy) +{ + register int* ixp; + register int* iyp; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n; i++, ixp+=(*incx), iyp+=(*incy)) + *iyp = *ixp; + + return 0; +} +int lcopy_(long* n, long* ix, long* incx, long* iy, long* incy) +{ + register long* ixp; + register long* iyp; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n;i++, ixp+=(*incx), iyp+=(*incy)) + *iyp = *ixp; + return 0; +}; +int scopy_(long* n, float* ix, long* incx, float* iy, long* incy) +{ + register float* ixp; + register float* iyp; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n;i++, ixp+=(*incx), iyp+=(*incy)) + *iyp = *ixp; + return 0; +}; + + + +int iscal_(long* n, int* ia, int* ix, long* incx) +{ + register int* ixp; + register int a = *ia; + register long i; + for(i = 1, ixp = ix; i <= *n; i++ , ixp+=(*incx)) + *ixp *= a; + return 0; +} +int lscal_(long* n, long* la, long* ix, long* incx) +{ + register long* ixp; + register long a = *la; + register long i; + for(i = 1, ixp = ix; i <= *n; i++ , ixp+=(*incx)) + *ixp *= a; + return 0; +}; +int sscal_(long* n, float* sa, float* ix, long* incx) +{ + register float* ixp; + register float a = *sa; + register long i; + for(i = 1, ixp = ix; i <= *n; i++ , ixp+=(*incx)) + *ixp *= a; + return 0; +}; + + +int iaxpy_(long* n, int* ia, int* ix, long* incx, int* iy, long* incy) +{ + register int* ixp; + register int* iyp; + register int a = *ia; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n; i++, ixp+=(*incx), iyp+=(*incy)) + *iyp += a*(*ixp); + return 0; +} +int laxpy_(long* n, long* la, long* ix, long* incx, long* iy, long* incy) +{ + register long* ixp; + register long* iyp; + register long a = *la; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n; i++, ixp+=(*incx), iyp+=(*incy)) + *iyp += a*(*ixp); + return 0; +}; +int saxpy_(long* n, float* sa, float* ix, long* incx, float* iy, long* incy) +{ + register float* ixp; + register float* iyp; + register float a = *sa; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n; i++, ixp+=(*incx), iyp+=(*incy)) + *iyp += a*(*ixp); + return 0; +}; + +// +// The following have been replaced by ftc translations of LINPACK +// routines. +// +/* +extern "C" int dscal_(long* n, double* da, double* ix, long* incx) +{ + register double* ixp; + register double a = *da; + register long i; + for(i = 1, ixp = ix; i <= *n; i++ , ixp+=(*incx)) + *ixp *= a; +}; +*/ + +/* +extern "C" int dcopy_(long* n, double* ix, long* incx, double* iy, long* incy) +{ + + register double* ixp; + register double* iyp; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n; i++, ixp+=(*incx), iyp+=(*incy)) + *iyp = *ixp; + +}; +*/ + +/* +extern "C" int daxpy_(long* n, double* da, double* ix, long* incx, double* iy, long* incy) +{ + register double* ixp; + register double* iyp; + register double a = *da; + register long i; + for(i = 1, ixp = ix, iyp = iy; i <= *n;i++, ixp+=(*incx), iyp+=(*incy)) + *iyp += a*(*ixp); +}; +*/ + + + diff --git a/src/matrix/camblas/blas.h b/src/matrix/camblas/blas.h new file mode 100644 index 0000000..6db761e --- /dev/null +++ b/src/matrix/camblas/blas.h @@ -0,0 +1,42 @@ +// +// Prototypes for BLAS Routines and Selected External Routines +// +#ifndef __FORTRAN_CALLS__ +// +// +// +#include "blasimpexp.h" + +extern "C" __IMPEXP__ int icopy_(long* n, int* ix, long* incx, int* iy, long* incy); +extern "C" __IMPEXP__ int lcopy_(long* n, long* ix, long* incx, long* iy, long* incy); +extern "C" __IMPEXP__ int scopy_(long* n, float* ix, long* incx, float* iy, long* incy); +extern "C" __IMPEXP__ int iscal_(long* n, int* ia, int* ix, long* incx); +extern "C" __IMPEXP__ int lscal_(long* n, long* la, long* ix, long* incx); +extern "C" __IMPEXP__ int sscal_(long* n, float* sa, float* ix, long* incx); +extern "C" __IMPEXP__ int iaxpy_(long* n, int* ia, int* ix, long* incx, int* iy, long* incy); +extern "C" __IMPEXP__ int laxpy_(long* n, long* la, long* ix, long* incx, long* iy, long* incy); +extern "C" __IMPEXP__ int saxpy_(long* n, float* sa, float* ix, long* incx, float* iy, long* incy); +// +// Double versions translated from Fortran to C using f2c translation +// +extern "C" int __IMPEXP__ dcopy_(long* n, double* ix, long* incx, double* iy, long* incy); +extern "C" int __IMPEXP__ dscal_(long* n, double* da, double* ix, long* incx); +extern "C" int __IMPEXP__ daxpy_(long* n, double* da, double* ix, long* incx, double* iy, long* incy); +// +// Matrix routines (f2c translations of Linpack routines) +// +extern "C" double dnrm2_(long* n, double* dx, long* incx); + +extern "C" int dgemm_(char* transa, char* transb, long* m, long* n, long* k, + double* alpha, double* a, long* lda, double* b, long* ldb, + double* beta, double* c, long* ldc, short f1, short f2); + +extern "C" int dgesvx_(char* fact, char* trans, long* n, long* nrhs, + double* a, long* lda, double* af, long* ldaf, long* ipiv, + char* equed, double* r, double* c, double* b, long* ldb, + double* x, long* ldx, double* rcond, double* ferr, double* berr, + double* work, long* iwork, long* info, + short fact_len, short trans_len, short equed_len); +#endif + + diff --git a/src/matrix/camblas/blasimpexp.h b/src/matrix/camblas/blasimpexp.h new file mode 100644 index 0000000..9a5e4bb --- /dev/null +++ b/src/matrix/camblas/blasimpexp.h @@ -0,0 +1,35 @@ +// +// Import/Export Directive for blas DLL +// +// Chris Anderson (C) UCLA 1997 +// +#undef __IMPEXP__ + +#ifdef __BCPLUSPLUS__ +#ifdef __EXPORT_BLAS__ +#define __IMPEXP__ __declspec(dllexport) +#endif +#ifdef __USEDLL__ +#define __IMPEXP__ __declspec(dllimport) +#endif +#endif + +#ifdef _MSC_VER +#ifdef __EXPORT_BLAS__ +#define __IMPEXP__ __declspec(dllexport) +#endif +#ifdef __USEDLL__ +#define __IMPEXP__ __declspec(dllimport) +#endif +#endif + + +#ifdef __STATIC__ +#undef __IMPEXP__ +#define __IMPEXP__ +#endif + +#ifndef __IMPEXP__ +#define __IMPEXP__ +#endif + diff --git a/src/matrix/camblas/cblasimpexp.h b/src/matrix/camblas/cblasimpexp.h new file mode 100644 index 0000000..d1d41f6 --- /dev/null +++ b/src/matrix/camblas/cblasimpexp.h @@ -0,0 +1,6 @@ +#ifdef __EXPORT_BLAS__ +#define __IMPEXP__ __declspec(dllexport) +#else +#define __IMPEXP__ +#endif + diff --git a/src/matrix/camblas/cinterface.pdf b/src/matrix/camblas/cinterface.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d30099ed2ff5d6b280fd81c6e7b6b6affc09fa1c GIT binary patch literal 239226 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

?82%^Mq9FHI`XhLP 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 z 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 literal 0 HcmV?d00001 diff --git a/src/matrix/camblas/dasum.c b/src/matrix/camblas/dasum.c new file mode 100644 index 0000000..c7148d2 --- /dev/null +++ b/src/matrix/camblas/dasum.c @@ -0,0 +1,84 @@ +/* DASUM.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" +doublereal __IMPEXP__ dasum_(n, dx, incx) +integer *n; +doublereal *dx; +integer *incx; +{ + /* System generated locals */ + integer i__1, i__2; + doublereal ret_val, d__1, d__2, d__3, d__4, d__5, d__6; + + /* Local variables */ + static integer i, m; + static doublereal dtemp; + static integer nincx, mp1; + + +/* takes the sum of the absolute values. */ +/* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dx; + + /* Function Body */ + ret_val = 0.; + dtemp = 0.; + if (*n <= 0) { + return ret_val; + } + if (*incx == 1) { + goto L20; + } + +/* code for increment not equal to 1 */ + + nincx = *n * *incx; + i__1 = nincx; + i__2 = *incx; + for (i = 1; i__2 < 0 ? i >= i__1 : i <= i__1; i += i__2) { + dtemp += (d__1 = dx[i], abs(d__1)); +/* L10: */ + } + ret_val = dtemp; + return ret_val; + +/* code for increment equal to 1 */ + + +/* clean-up loop */ + +L20: + m = *n % 6; + if (m == 0) { + goto L40; + } + i__2 = m; + for (i = 1; i <= i__2; ++i) { + dtemp += (d__1 = dx[i], abs(d__1)); +/* L30: */ + } + if (*n < 6) { + goto L60; + } +L40: + mp1 = m + 1; + i__2 = *n; + for (i = mp1; i <= i__2; i += 6) { + dtemp = dtemp + (d__1 = dx[i], abs(d__1)) + (d__2 = dx[i + 1], abs( + d__2)) + (d__3 = dx[i + 2], abs(d__3)) + (d__4 = dx[i + 3], + abs(d__4)) + (d__5 = dx[i + 4], abs(d__5)) + (d__6 = dx[i + 5] + , abs(d__6)); +/* L50: */ + } +L60: + ret_val = dtemp; + return ret_val; +} /* dasum_ */ + diff --git a/src/matrix/camblas/daxpy.c b/src/matrix/camblas/daxpy.c new file mode 100644 index 0000000..5b9c5b2 --- /dev/null +++ b/src/matrix/camblas/daxpy.c @@ -0,0 +1,93 @@ +/* DAXPY.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */ int __IMPEXP__ daxpy_(n, da, dx, incx, dy, incy) +integer *n; +doublereal *da, *dx; +integer *incx; +doublereal *dy; +integer *incy; +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + static integer i, m, ix, iy, mp1; + + +/* constant times a vector plus a vector. */ +/* uses unrolled loops for increments equal to one. */ +/* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dy; + --dx; + + /* Function Body */ + if (*n <= 0) { + return 0; + } + if (*da == 0.) { + return 0; + } + if (*incx == 1 && *incy == 1) { + goto L20; + } + +/* code for unequal increments or equal increments */ +/* not equal to 1 */ + + ix = 1; + iy = 1; + if (*incx < 0) { + ix = (-(*n) + 1) * *incx + 1; + } + if (*incy < 0) { + iy = (-(*n) + 1) * *incy + 1; + } + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + dy[iy] += *da * dx[ix]; + ix += *incx; + iy += *incy; +/* L10: */ + } + return 0; + +/* code for both increments equal to 1 */ + + +/* clean-up loop */ + +L20: + m = *n % 4; + if (m == 0) { + goto L40; + } + i__1 = m; + for (i = 1; i <= i__1; ++i) { + dy[i] += *da * dx[i]; +/* L30: */ + } + if (*n < 4) { + return 0; + } +L40: + mp1 = m + 1; + i__1 = *n; + for (i = mp1; i <= i__1; i += 4) { + dy[i] += *da * dx[i]; + dy[i + 1] += *da * dx[i + 1]; + dy[i + 2] += *da * dx[i + 2]; + dy[i + 3] += *da * dx[i + 3]; +/* L50: */ + } + return 0; +} /* daxpy_ */ + diff --git a/src/matrix/camblas/dcopy.c b/src/matrix/camblas/dcopy.c new file mode 100644 index 0000000..a603b49 --- /dev/null +++ b/src/matrix/camblas/dcopy.c @@ -0,0 +1,93 @@ +/* DCOPY.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */int __IMPEXP__ dcopy_(n, dx, incx, dy, incy) +integer *n; +doublereal *dx; +integer *incx; +doublereal *dy; +integer *incy; +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + static integer i, m, ix, iy, mp1; + + +/* copies a vector, x, to a vector, y. */ +/* uses unrolled loops for increments equal to one. */ +/* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dy; + --dx; + + /* Function Body */ + if (*n <= 0) { + return 0; + } + if (*incx == 1 && *incy == 1) { + goto L20; + } + +/* code for unequal increments or equal increments */ +/* not equal to 1 */ + + ix = 1; + iy = 1; + if (*incx < 0) { + ix = (-(*n) + 1) * *incx + 1; + } + if (*incy < 0) { + iy = (-(*n) + 1) * *incy + 1; + } + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + dy[iy] = dx[ix]; + ix += *incx; + iy += *incy; +/* L10: */ + } + return 0; + +/* code for both increments equal to 1 */ + + +/* clean-up loop */ + +L20: + m = *n % 7; + if (m == 0) { + goto L40; + } + i__1 = m; + for (i = 1; i <= i__1; ++i) { + dy[i] = dx[i]; +/* L30: */ + } + if (*n < 7) { + return 0; + } +L40: + mp1 = m + 1; + i__1 = *n; + for (i = mp1; i <= i__1; i += 7) { + dy[i] = dx[i]; + dy[i + 1] = dx[i + 1]; + dy[i + 2] = dx[i + 2]; + dy[i + 3] = dx[i + 3]; + dy[i + 4] = dx[i + 4]; + dy[i + 5] = dx[i + 5]; + dy[i + 6] = dx[i + 6]; +/* L50: */ + } + return 0; +} /* dcopy_ */ + diff --git a/src/matrix/camblas/ddot.c b/src/matrix/camblas/ddot.c new file mode 100644 index 0000000..2c28f38 --- /dev/null +++ b/src/matrix/camblas/ddot.c @@ -0,0 +1,95 @@ +/* DDOT.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" +doublereal __IMPEXP__ ddot_(n, dx, incx, dy, incy) +integer *n; +doublereal *dx; +integer *incx; +doublereal *dy; +integer *incy; +{ + /* System generated locals */ + integer i__1; + doublereal ret_val; + + /* Local variables */ + static integer i, m; + static doublereal dtemp; + static integer ix, iy, mp1; + + +/* forms the dot product of two vectors. */ +/* uses unrolled loops for increments equal to one. */ +/* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dy; + --dx; + + /* Function Body */ + ret_val = 0.; + dtemp = 0.; + if (*n <= 0) { + return ret_val; + } + if (*incx == 1 && *incy == 1) { + goto L20; + } + +/* code for unequal increments or equal increments */ +/* not equal to 1 */ + + ix = 1; + iy = 1; + if (*incx < 0) { + ix = (-(*n) + 1) * *incx + 1; + } + if (*incy < 0) { + iy = (-(*n) + 1) * *incy + 1; + } + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + dtemp += dx[ix] * dy[iy]; + ix += *incx; + iy += *incy; +/* L10: */ + } + ret_val = dtemp; + return ret_val; + +/* code for both increments equal to 1 */ + + +/* clean-up loop */ + +L20: + m = *n % 5; + if (m == 0) { + goto L40; + } + i__1 = m; + for (i = 1; i <= i__1; ++i) { + dtemp += dx[i] * dy[i]; +/* L30: */ + } + if (*n < 5) { + goto L60; + } +L40: + mp1 = m + 1; + i__1 = *n; + for (i = mp1; i <= i__1; i += 5) { + dtemp = dtemp + dx[i] * dy[i] + dx[i + 1] * dy[i + 1] + dx[i + 2] * + dy[i + 2] + dx[i + 3] * dy[i + 3] + dx[i + 4] * dy[i + 4]; +/* L50: */ + } +L60: + ret_val = dtemp; + return ret_val; +} /* ddot_ */ + diff --git a/src/matrix/camblas/dgemm.c b/src/matrix/camblas/dgemm.c new file mode 100644 index 0000000..bb2da6e --- /dev/null +++ b/src/matrix/camblas/dgemm.c @@ -0,0 +1,452 @@ +/* DGEMM.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* *********************************************************************** */ + +/* File of the DOUBLE PRECISION Level-3 BLAS. */ +/* ========================================== */ + +/* SUBROUTINE DGEMM ( TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, */ +/* $ BETA, C, LDC ) */ + +/* SUBROUTINE DSYMM ( SIDE, UPLO, M, N, ALPHA, A, LDA, B, LDB, */ +/* $ BETA, C, LDC ) */ + +/* SUBROUTINE DSYRK ( UPLO, TRANS, N, K, ALPHA, A, LDA, */ +/* $ BETA, C, LDC ) */ + +/* SUBROUTINE DSYR2K( UPLO, TRANS, N, K, ALPHA, A, LDA, B, LDB, */ +/* $ BETA, C, LDC ) */ + +/* SUBROUTINE DTRMM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, */ +/* $ B, LDB ) */ + +/* SUBROUTINE DTRSM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, */ +/* $ B, LDB ) */ + +/* See: */ + +/* Dongarra J. J., Du Croz J. J., Duff I. and Hammarling S. */ +/* A set of Level 3 Basic Linear Algebra Subprograms. Technical */ +/* Memorandum No.88 (Revision 1), Mathematics and Computer Science */ +/* Division, Argonne National Laboratory, 9700 South Cass Avenue, */ +/* Argonne, Illinois 60439. */ + + +/* *********************************************************************** */ + +/* Subroutine */ int __IMPEXP__ dgemm_(transa, transb, m, n, k, alpha, a, lda, b, ldb, + beta, c, ldc, transa_len, transb_len) +char *transa, *transb; +integer *m, *n, *k; +doublereal *alpha, *a; +integer *lda; +doublereal *b; +integer *ldb; +doublereal *beta, *c; +integer *ldc; +ftnlen transa_len; +ftnlen transb_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, i__1, i__2, + i__3; + + /* Local variables */ + static integer info; + static logical nota, notb; + static doublereal temp; + static integer i, j, l, ncola; + extern logical lsame_(); + static integer nrowa, nrowb; + extern /* Subroutine */ int xerbla_(); + +/* .. Scalar Arguments .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGEMM performs one of the matrix-matrix operations */ + +/* C := alpha*op( A )*op( B ) + beta*C, */ + +/* where op( X ) is one of */ + +/* op( X ) = X or op( X ) = X', */ + +/* alpha and beta are scalars, and A, B and C are matrices, with op( A ) +*/ +/* an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. +*/ + +/* Parameters */ +/* ========== */ + +/* TRANSA - CHARACTER*1. */ +/* On entry, TRANSA specifies the form of op( A ) to be used in +*/ +/* the matrix multiplication as follows: */ + +/* TRANSA = 'N' or 'n', op( A ) = A. */ + +/* TRANSA = 'T' or 't', op( A ) = A'. */ + +/* TRANSA = 'C' or 'c', op( A ) = A'. */ + +/* Unchanged on exit. */ + +/* TRANSB - CHARACTER*1. */ +/* On entry, TRANSB specifies the form of op( B ) to be used in +*/ +/* the matrix multiplication as follows: */ + +/* TRANSB = 'N' or 'n', op( B ) = B. */ + +/* TRANSB = 'T' or 't', op( B ) = B'. */ + +/* TRANSB = 'C' or 'c', op( B ) = B'. */ + +/* Unchanged on exit. */ + +/* M - INTEGER. */ +/* On entry, M specifies the number of rows of the matrix +*/ +/* op( A ) and of the matrix C. M must be at least zero. +*/ +/* Unchanged on exit. */ + +/* N - INTEGER. */ +/* On entry, N specifies the number of columns of the matrix +*/ +/* op( B ) and the number of columns of the matrix C. N must be +*/ +/* at least zero. */ +/* Unchanged on exit. */ + +/* K - INTEGER. */ +/* On entry, K specifies the number of columns of the matrix +*/ +/* op( A ) and the number of rows of the matrix op( B ). K must +*/ +/* be at least zero. */ +/* Unchanged on exit. */ + +/* ALPHA - DOUBLE PRECISION. */ +/* On entry, ALPHA specifies the scalar alpha. */ +/* Unchanged on exit. */ + +/* A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is +*/ +/* k when TRANSA = 'N' or 'n', and is m otherwise. */ +/* Before entry with TRANSA = 'N' or 'n', the leading m by k +*/ +/* part of the array A must contain the matrix A, otherwise +*/ +/* the leading k by m part of the array A must contain the +*/ +/* matrix A. */ +/* Unchanged on exit. */ + +/* LDA - INTEGER. */ +/* On entry, LDA specifies the first dimension of A as declared +*/ +/* in the calling (sub) program. When TRANSA = 'N' or 'n' then +*/ +/* LDA must be at least max( 1, m ), otherwise LDA must be at +*/ +/* least max( 1, k ). */ +/* Unchanged on exit. */ + +/* B - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is +*/ +/* n when TRANSB = 'N' or 'n', and is k otherwise. */ +/* Before entry with TRANSB = 'N' or 'n', the leading k by n +*/ +/* part of the array B must contain the matrix B, otherwise +*/ +/* the leading n by k part of the array B must contain the +*/ +/* matrix B. */ +/* Unchanged on exit. */ + +/* LDB - INTEGER. */ +/* On entry, LDB specifies the first dimension of B as declared +*/ +/* in the calling (sub) program. When TRANSB = 'N' or 'n' then +*/ +/* LDB must be at least max( 1, k ), otherwise LDB must be at +*/ +/* least max( 1, n ). */ +/* Unchanged on exit. */ + +/* BETA - DOUBLE PRECISION. */ +/* On entry, BETA specifies the scalar beta. When BETA is +*/ +/* supplied as zero then C need not be set on input. */ +/* Unchanged on exit. */ + +/* C - DOUBLE PRECISION array of DIMENSION ( LDC, n ). */ +/* Before entry, the leading m by n part of the array C must +*/ +/* contain the matrix C, except when beta is zero, in which +*/ +/* case C need not be set on entry. */ +/* On exit, the array C is overwritten by the m by n matrix +*/ +/* ( alpha*op( A )*op( B ) + beta*C ). */ + +/* LDC - INTEGER. */ +/* On entry, LDC specifies the first dimension of C as declared +*/ +/* in the calling (sub) program. LDC must be at least +*/ +/* max( 1, m ). */ +/* Unchanged on exit. */ + + +/* Level 3 Blas routine. */ + +/* -- Written on 8-February-1989. */ +/* Jack Dongarra, Argonne National Laboratory. */ +/* Iain Duff, AERE Harwell. */ +/* Jeremy Du Croz, Numerical Algorithms Group Ltd. */ +/* Sven Hammarling, Numerical Algorithms Group Ltd. */ + + +/* .. External Functions .. */ +/* .. External Subroutines .. */ +/* .. Intrinsic Functions .. */ +/* .. Local Scalars .. */ +/* .. Parameters .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Set NOTA and NOTB as true if A and B respectively are not +*/ +/* transposed and set NROWA, NCOLA and NROWB as the number of rows +*/ +/* and columns of A and the number of rows of B respectively. +*/ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + b_dim1 = *ldb; + b_offset = b_dim1 + 1; + b -= b_offset; + c_dim1 = *ldc; + c_offset = c_dim1 + 1; + c -= c_offset; + + /* Function Body */ + nota = lsame_(transa, "N", 1L, 1L); + notb = lsame_(transb, "N", 1L, 1L); + if (nota) { + nrowa = *m; + ncola = *k; + } else { + nrowa = *k; + ncola = *m; + } + if (notb) { + nrowb = *k; + } else { + nrowb = *n; + } + +/* Test the input parameters. */ + + info = 0; + if (! nota && ! lsame_(transa, "C", 1L, 1L) && ! lsame_(transa, "T", 1L, + 1L)) { + info = 1; + } else if (! notb && ! lsame_(transb, "C", 1L, 1L) && ! lsame_(transb, + "T", 1L, 1L)) { + info = 2; + } else if (*m < 0) { + info = 3; + } else if (*n < 0) { + info = 4; + } else if (*k < 0) { + info = 5; + } else if (*lda < max(1,nrowa)) { + info = 8; + } else if (*ldb < max(1,nrowb)) { + info = 10; + } else if (*ldc < max(1,*m)) { + info = 13; + } + if (info != 0) { + xerbla_("DGEMM ", &info, 6L); + return 0; + } + +/* Quick return if possible. */ + + if (*m == 0 || *n == 0 || (*alpha == 0. || *k == 0) && *beta == 1.) { + return 0; + } + +/* And if alpha.eq.zero. */ + + if (*alpha == 0.) { + if (*beta == 0.) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + c[i + j * c_dim1] = 0.; +/* L10: */ + } +/* L20: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + c[i + j * c_dim1] = *beta * c[i + j * c_dim1]; +/* L30: */ + } +/* L40: */ + } + } + return 0; + } + +/* Start the operations. */ + + if (notb) { + if (nota) { + +/* Form C := alpha*A*B + beta*C. */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (*beta == 0.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + c[i + j * c_dim1] = 0.; +/* L50: */ + } + } else if (*beta != 1.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + c[i + j * c_dim1] = *beta * c[i + j * c_dim1]; +/* L60: */ + } + } + i__2 = *k; + for (l = 1; l <= i__2; ++l) { + if (b[l + j * b_dim1] != 0.) { + temp = *alpha * b[l + j * b_dim1]; + i__3 = *m; + for (i = 1; i <= i__3; ++i) { + c[i + j * c_dim1] += temp * a[i + l * a_dim1]; +/* L70: */ + } + } +/* L80: */ + } +/* L90: */ + } + } else { + +/* Form C := alpha*A'*B + beta*C */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + temp = 0.; + i__3 = *k; + for (l = 1; l <= i__3; ++l) { + temp += a[l + i * a_dim1] * b[l + j * b_dim1]; +/* L100: */ + } + if (*beta == 0.) { + c[i + j * c_dim1] = *alpha * temp; + } else { + c[i + j * c_dim1] = *alpha * temp + *beta * c[i + j * + c_dim1]; + } +/* L110: */ + } +/* L120: */ + } + } + } else { + if (nota) { + +/* Form C := alpha*A*B' + beta*C */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (*beta == 0.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + c[i + j * c_dim1] = 0.; +/* L130: */ + } + } else if (*beta != 1.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + c[i + j * c_dim1] = *beta * c[i + j * c_dim1]; +/* L140: */ + } + } + i__2 = *k; + for (l = 1; l <= i__2; ++l) { + if (b[j + l * b_dim1] != 0.) { + temp = *alpha * b[j + l * b_dim1]; + i__3 = *m; + for (i = 1; i <= i__3; ++i) { + c[i + j * c_dim1] += temp * a[i + l * a_dim1]; +/* L150: */ + } + } +/* L160: */ + } +/* L170: */ + } + } else { + +/* Form C := alpha*A'*B' + beta*C */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + temp = 0.; + i__3 = *k; + for (l = 1; l <= i__3; ++l) { + temp += a[l + i * a_dim1] * b[j + l * b_dim1]; +/* L180: */ + } + if (*beta == 0.) { + c[i + j * c_dim1] = *alpha * temp; + } else { + c[i + j * c_dim1] = *alpha * temp + *beta * c[i + j * + c_dim1]; + } +/* L190: */ + } +/* L200: */ + } + } + } + + return 0; + +/* End of DGEMM . */ + +} /* dgemm_ */ + diff --git a/src/matrix/camblas/dgemv.c b/src/matrix/camblas/dgemv.c new file mode 100644 index 0000000..d8c2661 --- /dev/null +++ b/src/matrix/camblas/dgemv.c @@ -0,0 +1,375 @@ +/* DGEMV.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + + +/* *********************************************************************** */ + +/* File of the DOUBLE PRECISION Level-2 BLAS. */ +/* =========================================== */ + +/* SUBROUTINE DGEMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX, */ +/* $ BETA, Y, INCY ) */ + +/* SUBROUTINE DGBMV ( TRANS, M, N, KL, KU, ALPHA, A, LDA, X, INCX, */ +/* $ BETA, Y, INCY ) */ + +/* SUBROUTINE DSYMV ( UPLO, N, ALPHA, A, LDA, X, INCX, */ +/* $ BETA, Y, INCY ) */ + +/* SUBROUTINE DSBMV ( UPLO, N, K, ALPHA, A, LDA, X, INCX, */ +/* $ BETA, Y, INCY ) */ + +/* SUBROUTINE DSPMV ( UPLO, N, ALPHA, AP, X, INCX, BETA, Y, INCY ) */ + +/* SUBROUTINE DTRMV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX ) */ + +/* SUBROUTINE DTBMV ( UPLO, TRANS, DIAG, N, K, A, LDA, X, INCX ) */ + +/* SUBROUTINE DTPMV ( UPLO, TRANS, DIAG, N, AP, X, INCX ) */ + +/* SUBROUTINE DTRSV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX ) */ + +/* SUBROUTINE DTBSV ( UPLO, TRANS, DIAG, N, K, A, LDA, X, INCX ) */ + +/* SUBROUTINE DTPSV ( UPLO, TRANS, DIAG, N, AP, X, INCX ) */ + +/* SUBROUTINE DGER ( M, N, ALPHA, X, INCX, Y, INCY, A, LDA ) */ + +/* SUBROUTINE DSYR ( UPLO, N, ALPHA, X, INCX, A, LDA ) */ + +/* SUBROUTINE DSPR ( UPLO, N, ALPHA, X, INCX, AP ) */ + +/* SUBROUTINE DSYR2 ( UPLO, N, ALPHA, X, INCX, Y, INCY, A, LDA ) */ + +/* SUBROUTINE DSPR2 ( UPLO, N, ALPHA, X, INCX, Y, INCY, AP ) */ + +/* See: */ + +/* Dongarra J. J., Du Croz J. J., Hammarling S. and Hanson R. J.. */ +/* An extended set of Fortran Basic Linear Algebra Subprograms. */ + +/* Technical Memoranda Nos. 41 (revision 3) and 81, Mathematics */ +/* and Computer Science Division, Argonne National Laboratory, */ +/* 9700 South Cass Avenue, Argonne, Illinois 60439, US. */ + +/* Or */ + +/* NAG Technical Reports TR3/87 and TR4/87, Numerical Algorithms */ +/* Group Ltd., NAG Central Office, 256 Banbury Road, Oxford */ +/* OX2 7DE, UK, and Numerical Algorithms Group Inc., 1101 31st */ +/* Street, Suite 100, Downers Grove, Illinois 60515-1263, USA. */ + +/* *********************************************************************** */ + +/* Subroutine */ int __IMPEXP__ dgemv_(trans, m, n, alpha, a, lda, x, incx, beta, y, + incy, trans_len) +char *trans; +integer *m, *n; +doublereal *alpha, *a; +integer *lda; +doublereal *x; +integer *incx; +doublereal *beta, *y; +integer *incy; +ftnlen trans_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer info; + static doublereal temp; + static integer lenx, leny, i, j; + extern logical lsame_(); + static integer ix, iy, jx, jy, kx, ky; + extern /* Subroutine */ int xerbla_(); + +/* .. Scalar Arguments .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGEMV performs one of the matrix-vector operations */ + +/* y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, */ + +/* where alpha and beta are scalars, x and y are vectors and A is an */ +/* m by n matrix. */ + +/* Parameters */ +/* ========== */ + +/* TRANS - CHARACTER*1. */ +/* On entry, TRANS specifies the operation to be performed as */ +/* follows: */ + +/* TRANS = 'N' or 'n' y := alpha*A*x + beta*y. */ + +/* TRANS = 'T' or 't' y := alpha*A'*x + beta*y. */ + +/* TRANS = 'C' or 'c' y := alpha*A'*x + beta*y. */ + +/* Unchanged on exit. */ + +/* M - INTEGER. */ +/* On entry, M specifies the number of rows of the matrix A. */ +/* M must be at least zero. */ +/* Unchanged on exit. */ + +/* N - INTEGER. */ +/* On entry, N specifies the number of columns of the matrix A. +*/ +/* N must be at least zero. */ +/* Unchanged on exit. */ + +/* ALPHA - DOUBLE PRECISION. */ +/* On entry, ALPHA specifies the scalar alpha. */ +/* Unchanged on exit. */ + +/* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). */ +/* Before entry, the leading m by n part of the array A must */ +/* contain the matrix of coefficients. */ +/* Unchanged on exit. */ + +/* LDA - INTEGER. */ +/* On entry, LDA specifies the first dimension of A as declared +*/ +/* in the calling (sub) program. LDA must be at least */ +/* max( 1, m ). */ +/* Unchanged on exit. */ + +/* X - DOUBLE PRECISION array of DIMENSION at least */ +/* ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n' */ +/* and at least */ +/* ( 1 + ( m - 1 )*abs( INCX ) ) otherwise. */ +/* Before entry, the incremented array X must contain the */ +/* vector x. */ +/* Unchanged on exit. */ + +/* INCX - INTEGER. */ +/* On entry, INCX specifies the increment for the elements of */ +/* X. INCX must not be zero. */ +/* Unchanged on exit. */ + +/* BETA - DOUBLE PRECISION. */ +/* On entry, BETA specifies the scalar beta. When BETA is */ +/* supplied as zero then Y need not be set on input. */ +/* Unchanged on exit. */ + +/* Y - DOUBLE PRECISION array of DIMENSION at least */ +/* ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n' */ +/* and at least */ +/* ( 1 + ( n - 1 )*abs( INCY ) ) otherwise. */ +/* Before entry with BETA non-zero, the incremented array Y */ +/* must contain the vector y. On exit, Y is overwritten by the +*/ +/* updated vector y. */ + +/* INCY - INTEGER. */ +/* On entry, INCY specifies the increment for the elements of */ +/* Y. INCY must not be zero. */ +/* Unchanged on exit. */ + + +/* Level 2 Blas routine. */ + +/* -- Written on 22-October-1986. */ +/* Jack Dongarra, Argonne National Lab. */ +/* Jeremy Du Croz, Nag Central Office. */ +/* Sven Hammarling, Nag Central Office. */ +/* Richard Hanson, Sandia National Labs. */ + + +/* .. Parameters .. */ +/* .. Local Scalars .. */ +/* .. External Functions .. */ +/* .. External Subroutines .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --x; + --y; + + /* Function Body */ + info = 0; + if (! lsame_(trans, "N", 1L, 1L) && ! lsame_(trans, "T", 1L, 1L) && ! + lsame_(trans, "C", 1L, 1L)) { + info = 1; + } else if (*m < 0) { + info = 2; + } else if (*n < 0) { + info = 3; + } else if (*lda < max(1,*m)) { + info = 6; + } else if (*incx == 0) { + info = 8; + } else if (*incy == 0) { + info = 11; + } + if (info != 0) { + xerbla_("DGEMV ", &info, 6L); + return 0; + } + +/* Quick return if possible. */ + + if (*m == 0 || *n == 0 || *alpha == 0. && *beta == 1.) { + return 0; + } + +/* Set LENX and LENY, the lengths of the vectors x and y, and set +*/ +/* up the start points in X and Y. */ + + if (lsame_(trans, "N", 1L, 1L)) { + lenx = *n; + leny = *m; + } else { + lenx = *m; + leny = *n; + } + if (*incx > 0) { + kx = 1; + } else { + kx = 1 - (lenx - 1) * *incx; + } + if (*incy > 0) { + ky = 1; + } else { + ky = 1 - (leny - 1) * *incy; + } + +/* Start the operations. In this version the elements of A are */ +/* accessed sequentially with one pass through A. */ + +/* First form y := beta*y. */ + + if (*beta != 1.) { + if (*incy == 1) { + if (*beta == 0.) { + i__1 = leny; + for (i = 1; i <= i__1; ++i) { + y[i] = 0.; +/* L10: */ + } + } else { + i__1 = leny; + for (i = 1; i <= i__1; ++i) { + y[i] = *beta * y[i]; +/* L20: */ + } + } + } else { + iy = ky; + if (*beta == 0.) { + i__1 = leny; + for (i = 1; i <= i__1; ++i) { + y[iy] = 0.; + iy += *incy; +/* L30: */ + } + } else { + i__1 = leny; + for (i = 1; i <= i__1; ++i) { + y[iy] = *beta * y[iy]; + iy += *incy; +/* L40: */ + } + } + } + } + if (*alpha == 0.) { + return 0; + } + if (lsame_(trans, "N", 1L, 1L)) { + +/* Form y := alpha*A*x + y. */ + + jx = kx; + if (*incy == 1) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (x[jx] != 0.) { + temp = *alpha * x[jx]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + y[i] += temp * a[i + j * a_dim1]; +/* L50: */ + } + } + jx += *incx; +/* L60: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (x[jx] != 0.) { + temp = *alpha * x[jx]; + iy = ky; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + y[iy] += temp * a[i + j * a_dim1]; + iy += *incy; +/* L70: */ + } + } + jx += *incx; +/* L80: */ + } + } + } else { + +/* Form y := alpha*A'*x + y. */ + + jy = ky; + if (*incx == 1) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + temp = 0.; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + temp += a[i + j * a_dim1] * x[i]; +/* L90: */ + } + y[jy] += *alpha * temp; + jy += *incy; +/* L100: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + temp = 0.; + ix = kx; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + temp += a[i + j * a_dim1] * x[ix]; + ix += *incx; +/* L110: */ + } + y[jy] += *alpha * temp; + jy += *incy; +/* L120: */ + } + } + } + + return 0; + +/* End of DGEMV . */ + +} /* dgemv_ */ + diff --git a/src/matrix/camblas/dger.c b/src/matrix/camblas/dger.c new file mode 100644 index 0000000..886f3e3 --- /dev/null +++ b/src/matrix/camblas/dger.c @@ -0,0 +1,197 @@ +/* DGER.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + + +/* *********************************************************************** */ + +/* Subroutine */ int __IMPEXP__ dger_(m, n, alpha, x, incx, y, incy, a, lda) +integer *m, *n; +doublereal *alpha, *x; +integer *incx; +doublereal *y; +integer *incy; +doublereal *a; +integer *lda; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer info; + static doublereal temp; + static integer i, j, ix, jy, kx; + extern /* Subroutine */ int xerbla_(); + +/* .. Scalar Arguments .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGER performs the rank 1 operation */ + +/* A := alpha*x*y' + A, */ + +/* where alpha is a scalar, x is an m element vector, y is an n element +*/ +/* vector and A is an m by n matrix. */ + +/* Parameters */ +/* ========== */ + +/* M - INTEGER. */ +/* On entry, M specifies the number of rows of the matrix A. */ +/* M must be at least zero. */ +/* Unchanged on exit. */ + +/* N - INTEGER. */ +/* On entry, N specifies the number of columns of the matrix A. +*/ +/* N must be at least zero. */ +/* Unchanged on exit. */ + +/* ALPHA - DOUBLE PRECISION. */ +/* On entry, ALPHA specifies the scalar alpha. */ +/* Unchanged on exit. */ + +/* X - DOUBLE PRECISION array of dimension at least */ +/* ( 1 + ( m - 1 )*abs( INCX ) ). */ +/* Before entry, the incremented array X must contain the m */ +/* element vector x. */ +/* Unchanged on exit. */ + +/* INCX - INTEGER. */ +/* On entry, INCX specifies the increment for the elements of */ +/* X. INCX must not be zero. */ +/* Unchanged on exit. */ + +/* Y - DOUBLE PRECISION array of dimension at least */ +/* ( 1 + ( n - 1 )*abs( INCY ) ). */ +/* Before entry, the incremented array Y must contain the n */ +/* element vector y. */ +/* Unchanged on exit. */ + +/* INCY - INTEGER. */ +/* On entry, INCY specifies the increment for the elements of */ +/* Y. INCY must not be zero. */ +/* Unchanged on exit. */ + +/* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). */ +/* Before entry, the leading m by n part of the array A must */ +/* contain the matrix of coefficients. On exit, A is */ +/* overwritten by the updated matrix. */ + +/* LDA - INTEGER. */ +/* On entry, LDA specifies the first dimension of A as declared +*/ +/* in the calling (sub) program. LDA must be at least */ +/* max( 1, m ). */ +/* Unchanged on exit. */ + + +/* Level 2 Blas routine. */ + +/* -- Written on 22-October-1986. */ +/* Jack Dongarra, Argonne National Lab. */ +/* Jeremy Du Croz, Nag Central Office. */ +/* Sven Hammarling, Nag Central Office. */ +/* Richard Hanson, Sandia National Labs. */ + + +/* .. Parameters .. */ +/* .. Local Scalars .. */ +/* .. External Subroutines .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + --x; + --y; + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + + /* Function Body */ + info = 0; + if (*m < 0) { + info = 1; + } else if (*n < 0) { + info = 2; + } else if (*incx == 0) { + info = 5; + } else if (*incy == 0) { + info = 7; + } else if (*lda < max(1,*m)) { + info = 9; + } + if (info != 0) { + xerbla_("DGER ", &info, 6L); + return 0; + } + +/* Quick return if possible. */ + + if (*m == 0 || *n == 0 || *alpha == 0.) { + return 0; + } + +/* Start the operations. In this version the elements of A are */ +/* accessed sequentially with one pass through A. */ + + if (*incy > 0) { + jy = 1; + } else { + jy = 1 - (*n - 1) * *incy; + } + if (*incx == 1) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (y[jy] != 0.) { + temp = *alpha * y[jy]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + a[i + j * a_dim1] += x[i] * temp; +/* L10: */ + } + } + jy += *incy; +/* L20: */ + } + } else { + if (*incx > 0) { + kx = 1; + } else { + kx = 1 - (*m - 1) * *incx; + } + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (y[jy] != 0.) { + temp = *alpha * y[jy]; + ix = kx; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + a[i + j * a_dim1] += x[ix] * temp; + ix += *incx; +/* L30: */ + } + } + jy += *incy; +/* L40: */ + } + } + + return 0; + +/* End of DGER . */ + +} /* dger_ */ + diff --git a/src/matrix/camblas/dnrm2.c b/src/matrix/camblas/dnrm2.c new file mode 100644 index 0000000..759ca61 --- /dev/null +++ b/src/matrix/camblas/dnrm2.c @@ -0,0 +1,213 @@ +/* DNRM2.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" +doublereal __IMPEXP__ dnrm2_(n, dx, incx) +integer *n; +doublereal *dx; +integer *incx; +{ + /* Initialized data */ + + static doublereal zero = 0.; + static doublereal one = 1.; + static doublereal cutlo = 8.232e-11; + static doublereal cuthi = 1.304e19; + + /* Format strings */ + static char fmt_30[] = ""; + static char fmt_50[] = ""; + static char fmt_70[] = ""; + static char fmt_110[] = ""; + + /* System generated locals */ + integer i__1; + doublereal ret_val, d__1; + + /* Builtin functions */ + double sqrt(); + + /* Local variables */ + static doublereal xmax; + static integer next, i, j, ix; + static doublereal hitest, sum; + + /* Assigned format variables */ + char *next_fmt; + + /* Parameter adjustments */ + --dx; + + /* Function Body */ + +/* euclidean norm of the n-vector stored in dx() with storage */ +/* increment incx . */ +/* if n .le. 0 return with result = 0. */ +/* if n .ge. 1 then incx must be .ge. 1 */ + +/* c.l.lawson, 1978 jan 08 */ +/* modified to correct failure to update ix, 1/25/92. */ +/* modified 3/93 to return if incx .le. 0. */ + +/* four phase method using two built-in constants that are */ +/* hopefully applicable to all machines. */ +/* cutlo = maximum of dsqrt(u/eps) over all known machines. */ +/* cuthi = minimum of dsqrt(v) over all known machines. */ +/* where */ +/* eps = smallest no. such that eps + 1. .gt. 1. */ +/* u = smallest positive no. (underflow limit) */ +/* v = largest no. (overflow limit) */ + +/* brief outline of algorithm.. */ + +/* phase 1 scans zero components. */ +/* move to phase 2 when a component is nonzero and .le. cutlo */ +/* move to phase 3 when a component is .gt. cutlo */ +/* move to phase 4 when a component is .ge. cuthi/m */ +/* where m = n for x() real and m = 2*n for complex. */ + +/* values for cutlo and cuthi.. */ +/* from the environmental parameters listed in the imsl converter */ +/* document the limiting values are as follows.. */ +/* cutlo, s.p. u/eps = 2**(-102) for honeywell. close seconds are +*/ +/* univac and dec at 2**(-103) */ +/* thus cutlo = 2**(-51) = 4.44089e-16 */ +/* cuthi, s.p. v = 2**127 for univac, honeywell, and dec. */ +/* thus cuthi = 2**(63.5) = 1.30438e19 */ +/* cutlo, d.p. u/eps = 2**(-67) for honeywell and dec. */ +/* thus cutlo = 2**(-33.5) = 8.23181d-11 */ +/* cuthi, d.p. same as s.p. cuthi = 1.30438d19 */ +/* data cutlo, cuthi / 8.232d-11, 1.304d19 / */ +/* data cutlo, cuthi / 4.441e-16, 1.304e19 / */ + + if (*n > 0 && *incx > 0) { + goto L10; + } + ret_val = zero; + goto L300; + +L10: + next = 0; + next_fmt = fmt_30; + sum = zero; + i = 1; + ix = 1; +/* begin main loop */ +L20: + switch ((int)next) { + case 0: goto L30; + case 1: goto L50; + case 2: goto L70; + case 3: goto L110; + } +L30: + if ((d__1 = dx[i], abs(d__1)) > cutlo) { + goto L85; + } + next = 1; + next_fmt = fmt_50; + xmax = zero; + +/* phase 1. sum is zero */ + +L50: + if (dx[i] == zero) { + goto L200; + } + if ((d__1 = dx[i], abs(d__1)) > cutlo) { + goto L85; + } + +/* prepare for phase 2. */ + next = 2; + next_fmt = fmt_70; + goto L105; + +/* prepare for phase 4. */ + +L100: + ix = j; + next = 3; + next_fmt = fmt_110; + sum = sum / dx[i] / dx[i]; +L105: + xmax = (d__1 = dx[i], abs(d__1)); + goto L115; + +/* phase 2. sum is small. */ +/* scale to avoid destructive underflow. */ + +L70: + if ((d__1 = dx[i], abs(d__1)) > cutlo) { + goto L75; + } + +/* common code for phases 2 and 4. */ +/* in phase 4 sum is large. scale to avoid overflow. +*/ + +L110: + if ((d__1 = dx[i], abs(d__1)) <= xmax) { + goto L115; + } +/* Computing 2nd power */ + d__1 = xmax / dx[i]; + sum = one + sum * (d__1 * d__1); + xmax = (d__1 = dx[i], abs(d__1)); + goto L200; + +L115: +/* Computing 2nd power */ + d__1 = dx[i] / xmax; + sum += d__1 * d__1; + goto L200; + + +/* prepare for phase 3. */ + +L75: + sum = sum * xmax * xmax; + + +/* for real or d.p. set hitest = cuthi/n */ +/* for complex set hitest = cuthi/(2*n) */ + +L85: + hitest = cuthi / (real) (*n); + +/* phase 3. sum is mid-range. no scaling. */ + + i__1 = *n; + for (j = ix; j <= i__1; ++j) { + if ((d__1 = dx[i], abs(d__1)) >= hitest) { + goto L100; + } +/* Computing 2nd power */ + d__1 = dx[i]; + sum += d__1 * d__1; + i += *incx; +/* L95: */ + } + ret_val = sqrt(sum); + goto L300; + +L200: + ++ix; + i += *incx; + if (ix <= *n) { + goto L20; + } + +/* end of main loop. */ + +/* compute square root and adjust for scaling. */ + + ret_val = xmax * sqrt(sum); +L300: + return ret_val; +} /* dnrm2_ */ + diff --git a/src/matrix/camblas/drot.c b/src/matrix/camblas/drot.c new file mode 100644 index 0000000..646282e --- /dev/null +++ b/src/matrix/camblas/drot.c @@ -0,0 +1,128 @@ +/* DROT.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* DECK DROT */ +/* Subroutine */ int __IMPEXP__ drot_(n, dx, incx, dy, incy, dc, ds) +integer *n; +doublereal *dx; +integer *incx; +doublereal *dy; +integer *incy; +doublereal *dc, *ds; +{ + /* Initialized data */ + + static doublereal zero = 0.; + static doublereal one = 1.; + + /* System generated locals */ + integer i__1, i__2; + + /* Local variables */ + static integer i; + static doublereal w, z; + static integer kx, ky, nsteps; + +/* ***BEGIN PROLOGUE DROT */ +/* ***DATE WRITTEN 791001 (YYMMDD) */ +/* ***REVISION DATE 861211 (YYMMDD) */ +/* ***CATEGORY NO. D1A8 */ +/* ***KEYWORDS LIBRARY=SLATEC(BLAS), */ +/* TYPE=DOUBLE PRECISION(SROT-S DROT-D CSROT-C), */ +/* GIVENS ROTATION,GIVENS TRANSFORMATION,LINEAR ALGEBRA, */ +/* PLANE ROTATION,VECTOR */ +/* ***AUTHOR LAWSON, C. L., (JPL) */ +/* HANSON, R. J., (SNLA) */ +/* KINCAID, D. R., (U. OF TEXAS) */ +/* KROGH, F. T., (JPL) */ +/* ***PURPOSE APPLY d.p. Givens rotation */ +/* ***DESCRIPTION */ + +/* B L A S Subprogram */ +/* Description of Parameters */ + +/* --Input-- */ +/* N number of elements in input vector(s) */ +/* DX double precision vector with N elements */ +/* INCX storage spacing between elements of DX */ +/* DY double precision vector with N elements */ +/* INCY storage spacing between elements of DY */ +/* DC D.P. element of rotation matrix */ +/* DS D.P. element of rotation matrix */ + +/* --Output-- */ +/* DX rotated vector (unchanged if N .LE. 0) */ +/* DY rotated vector (unchanged if N .LE. 0) */ + +/* Multiply the 2 X 2 matrix ( DC DS) times the 2 X N matrix (DX**T) +*/ +/* (-DS DC) (DY**T) +*/ +/* where **T indicates transpose. The elements of DX are in */ +/* DX(LX+I*INCX), I = 0 to N-1, where LX = 1 if INCX .GE. 0, else */ +/* LX = (-INCX)*N, and similarly for DY using LY and INCY. */ +/* ***REFERENCES LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., */ +/* *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, +*/ +/* ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL */ +/* SOFTWARE, VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 +*/ +/* ***ROUTINES CALLED (NONE) */ +/* ***END PROLOGUE DROT */ + + /* Parameter adjustments */ + --dy; + --dx; + + /* Function Body */ +/* ***FIRST EXECUTABLE STATEMENT DROT */ + if (*n <= 0 || *ds == zero && *dc == one) { + goto L40; + } + if (! (*incx == *incy && *incx > 0)) { + goto L20; + } + + nsteps = *incx * *n; + i__1 = nsteps; + i__2 = *incx; + for (i = 1; i__2 < 0 ? i >= i__1 : i <= i__1; i += i__2) { + w = dx[i]; + z = dy[i]; + dx[i] = *dc * w + *ds * z; + dy[i] = -(*ds) * w + *dc * z; +/* L10: */ + } + goto L40; + +L20: + kx = 1; + ky = 1; + + if (*incx < 0) { + kx = 1 - (*n - 1) * *incx; + } + if (*incy < 0) { + ky = 1 - (*n - 1) * *incy; + } + + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + w = dx[kx]; + z = dy[ky]; + dx[kx] = *dc * w + *ds * z; + dy[ky] = -(*ds) * w + *dc * z; + kx += *incx; + ky += *incy; +/* L30: */ + } +L40: + + return 0; +} /* drot_ */ + diff --git a/src/matrix/camblas/dscal.c b/src/matrix/camblas/dscal.c new file mode 100644 index 0000000..8204ed7 --- /dev/null +++ b/src/matrix/camblas/dscal.c @@ -0,0 +1,79 @@ +/* DSCAL.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */ int __IMPEXP__ dscal_(n, da, dx, incx) +integer *n; +doublereal *da, *dx; +integer *incx; +{ + /* System generated locals */ + integer i__1, i__2; + + /* Local variables */ + static integer i, m, nincx, mp1; + + +/* scales a vector by a constant. */ +/* uses unrolled loops for increment equal to one. */ +/* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dx; + + /* Function Body */ + if (*n <= 0) { + return 0; + } + if (*incx == 1) { + goto L20; + } + +/* code for increment not equal to 1 */ + + nincx = *n * *incx; + i__1 = nincx; + i__2 = *incx; + for (i = 1; i__2 < 0 ? i >= i__1 : i <= i__1; i += i__2) { + dx[i] = *da * dx[i]; +/* L10: */ + } + return 0; + +/* code for increment equal to 1 */ + + +/* clean-up loop */ + +L20: + m = *n % 5; + if (m == 0) { + goto L40; + } + i__2 = m; + for (i = 1; i <= i__2; ++i) { + dx[i] = *da * dx[i]; +/* L30: */ + } + if (*n < 5) { + return 0; + } +L40: + mp1 = m + 1; + i__2 = *n; + for (i = mp1; i <= i__2; i += 5) { + dx[i] = *da * dx[i]; + dx[i + 1] = *da * dx[i + 1]; + dx[i + 2] = *da * dx[i + 2]; + dx[i + 3] = *da * dx[i + 3]; + dx[i + 4] = *da * dx[i + 4]; +/* L50: */ + } + return 0; +} /* dscal_ */ + diff --git a/src/matrix/camblas/dswap.c b/src/matrix/camblas/dswap.c new file mode 100644 index 0000000..0b3b019 --- /dev/null +++ b/src/matrix/camblas/dswap.c @@ -0,0 +1,101 @@ +/* DSWAP.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */ int __IMPEXP__ dswap_(n, dx, incx, dy, incy) +integer *n; +doublereal *dx; +integer *incx; +doublereal *dy; +integer *incy; +{ + /* System generated locals */ + integer i__1; + + /* Local variables */ + static integer i, m; + static doublereal dtemp; + static integer ix, iy, mp1; + + +/* interchanges two vectors. */ +/* uses unrolled loops for increments equal one. */ +/* jack dongarra, linpack, 3/11/78. */ + + + /* Parameter adjustments */ + --dy; + --dx; + + /* Function Body */ + if (*n <= 0) { + return 0; + } + if (*incx == 1 && *incy == 1) { + goto L20; + } + +/* code for unequal increments or equal increments not equal */ +/* to 1 */ + + ix = 1; + iy = 1; + if (*incx < 0) { + ix = (-(*n) + 1) * *incx + 1; + } + if (*incy < 0) { + iy = (-(*n) + 1) * *incy + 1; + } + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + dtemp = dx[ix]; + dx[ix] = dy[iy]; + dy[iy] = dtemp; + ix += *incx; + iy += *incy; +/* L10: */ + } + return 0; + +/* code for both increments equal to 1 */ + + +/* clean-up loop */ + +L20: + m = *n % 3; + if (m == 0) { + goto L40; + } + i__1 = m; + for (i = 1; i <= i__1; ++i) { + dtemp = dx[i]; + dx[i] = dy[i]; + dy[i] = dtemp; +/* L30: */ + } + if (*n < 3) { + return 0; + } +L40: + mp1 = m + 1; + i__1 = *n; + for (i = mp1; i <= i__1; i += 3) { + dtemp = dx[i]; + dx[i] = dy[i]; + dy[i] = dtemp; + dtemp = dx[i + 1]; + dx[i + 1] = dy[i + 1]; + dy[i + 1] = dtemp; + dtemp = dx[i + 2]; + dx[i + 2] = dy[i + 2]; + dy[i + 2] = dtemp; +/* L50: */ + } + return 0; +} /* dswap_ */ + diff --git a/src/matrix/camblas/dsymv.c b/src/matrix/camblas/dsymv.c new file mode 100644 index 0000000..3f698a4 --- /dev/null +++ b/src/matrix/camblas/dsymv.c @@ -0,0 +1,301 @@ + +/* -- translated by f2c (version 19940927). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */ int __IMPEXP__ dsymv_(char *uplo, integer *n, doublereal *alpha, + doublereal *a, integer *lda, doublereal *x, integer *incx, doublereal + *beta, doublereal *y, integer *incy) +{ + + + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer info; + static doublereal temp1, temp2; + static integer i, j; + extern logical lsame_(char *, char *); + static integer ix, iy, jx, jy, kx, ky; + extern /* Subroutine */ int xerbla_(char *, integer *); + + +/* Purpose + ======= + + DSYMV performs the matrix-vector operation + + y := alpha*A*x + beta*y, + + where alpha and beta are scalars, x and y are n element vectors and + A is an n by n symmetric matrix. + + Parameters + ========== + + UPLO - CHARACTER*1. + On entry, UPLO specifies whether the upper or lower + triangular part of the array A is to be referenced as + follows: + + UPLO = 'U' or 'u' Only the upper triangular part of A + is to be referenced. + + UPLO = 'L' or 'l' Only the lower triangular part of A + is to be referenced. + + Unchanged on exit. + + N - INTEGER. + On entry, N specifies the order of the matrix A. + N must be at least zero. + Unchanged on exit. + + ALPHA - DOUBLE PRECISION. + On entry, ALPHA specifies the scalar alpha. + Unchanged on exit. + + A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). + Before entry with UPLO = 'U' or 'u', the leading n by n + upper triangular part of the array A must contain the upper + + triangular part of the symmetric matrix and the strictly + lower triangular part of A is not referenced. + Before entry with UPLO = 'L' or 'l', the leading n by n + lower triangular part of the array A must contain the lower + + triangular part of the symmetric matrix and the strictly + upper triangular part of A is not referenced. + Unchanged on exit. + + LDA - INTEGER. + On entry, LDA specifies the first dimension of A as declared + + in the calling (sub) program. LDA must be at least + max( 1, n ). + Unchanged on exit. + + X - DOUBLE PRECISION array of dimension at least + ( 1 + ( n - 1 )*abs( INCX ) ). + Before entry, the incremented array X must contain the n + element vector x. + Unchanged on exit. + + INCX - INTEGER. + On entry, INCX specifies the increment for the elements of + X. INCX must not be zero. + Unchanged on exit. + + BETA - DOUBLE PRECISION. + On entry, BETA specifies the scalar beta. When BETA is + supplied as zero then Y need not be set on input. + Unchanged on exit. + + Y - DOUBLE PRECISION array of dimension at least + ( 1 + ( n - 1 )*abs( INCY ) ). + Before entry, the incremented array Y must contain the n + element vector y. On exit, Y is overwritten by the updated + vector y. + + INCY - INTEGER. + On entry, INCY specifies the increment for the elements of + Y. INCY must not be zero. + Unchanged on exit. + + + Level 2 Blas routine. + + -- Written on 22-October-1986. + Jack Dongarra, Argonne National Lab. + Jeremy Du Croz, Nag Central Office. + Sven Hammarling, Nag Central Office. + Richard Hanson, Sandia National Labs. + + + + Test the input parameters. + + + Parameter adjustments + Function Body */ +#define X(I) x[(I)-1] +#define Y(I) y[(I)-1] + +#define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] + + info = 0; + if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { + info = 1; + } else if (*n < 0) { + info = 2; + } else if (*lda < max(1,*n)) { + info = 5; + } else if (*incx == 0) { + info = 7; + } else if (*incy == 0) { + info = 10; + } + if (info != 0) { + xerbla_("DSYMV ", &info); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0 || *alpha == 0. && *beta == 1.) { + return 0; + } + +/* Set up the start points in X and Y. */ + + if (*incx > 0) { + kx = 1; + } else { + kx = 1 - (*n - 1) * *incx; + } + if (*incy > 0) { + ky = 1; + } else { + ky = 1 - (*n - 1) * *incy; + } + +/* Start the operations. In this version the elements of A are + accessed sequentially with one pass through the triangular part + of A. + + First form y := beta*y. */ + + if (*beta != 1.) { + if (*incy == 1) { + if (*beta == 0.) { + i__1 = *n; + for (i = 1; i <= *n; ++i) { + Y(i) = 0.; +/* L10: */ + } + } else { + i__1 = *n; + for (i = 1; i <= *n; ++i) { + Y(i) = *beta * Y(i); +/* L20: */ + } + } + } else { + iy = ky; + if (*beta == 0.) { + i__1 = *n; + for (i = 1; i <= *n; ++i) { + Y(iy) = 0.; + iy += *incy; +/* L30: */ + } + } else { + i__1 = *n; + for (i = 1; i <= *n; ++i) { + Y(iy) = *beta * Y(iy); + iy += *incy; +/* L40: */ + } + } + } + } + if (*alpha == 0.) { + return 0; + } + if (lsame_(uplo, "U")) { + +/* Form y when A is stored in upper triangle. */ + + if (*incx == 1 && *incy == 1) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + temp1 = *alpha * X(j); + temp2 = 0.; + i__2 = j - 1; + for (i = 1; i <= j-1; ++i) { + Y(i) += temp1 * A(i,j); + temp2 += A(i,j) * X(i); +/* L50: */ + } + Y(j) = Y(j) + temp1 * A(j,j) + *alpha * temp2; +/* L60: */ + } + } else { + jx = kx; + jy = ky; + i__1 = *n; + for (j = 1; j <= *n; ++j) { + temp1 = *alpha * X(jx); + temp2 = 0.; + ix = kx; + iy = ky; + i__2 = j - 1; + for (i = 1; i <= j-1; ++i) { + Y(iy) += temp1 * A(i,j); + temp2 += A(i,j) * X(ix); + ix += *incx; + iy += *incy; +/* L70: */ + } + Y(jy) = Y(jy) + temp1 * A(j,j) + *alpha * temp2; + jx += *incx; + jy += *incy; +/* L80: */ + } + } + } else { + +/* Form y when A is stored in lower triangle. */ + + if (*incx == 1 && *incy == 1) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + temp1 = *alpha * X(j); + temp2 = 0.; + Y(j) += temp1 * A(j,j); + i__2 = *n; + for (i = j + 1; i <= *n; ++i) { + Y(i) += temp1 * A(i,j); + temp2 += A(i,j) * X(i); +/* L90: */ + } + Y(j) += *alpha * temp2; +/* L100: */ + } + } else { + jx = kx; + jy = ky; + i__1 = *n; + for (j = 1; j <= *n; ++j) { + temp1 = *alpha * X(jx); + temp2 = 0.; + Y(jy) += temp1 * A(j,j); + ix = jx; + iy = jy; + i__2 = *n; + for (i = j + 1; i <= *n; ++i) { + ix += *incx; + iy += *incy; + Y(iy) += temp1 * A(i,j); + temp2 += A(i,j) * X(ix); +/* L110: */ + } + Y(jy) += *alpha * temp2; + jx += *incx; + jy += *incy; +/* L120: */ + } + } + } + + return 0; + +/* End of DSYMV . */ + +} /* dsymv_ */ + diff --git a/src/matrix/camblas/dsyr2.c b/src/matrix/camblas/dsyr2.c new file mode 100644 index 0000000..2738d99 --- /dev/null +++ b/src/matrix/camblas/dsyr2.c @@ -0,0 +1,265 @@ + +/* -- translated by f2c (version 19940927). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */ int __IMPEXP__ dsyr2_(char *uplo, integer *n, doublereal *alpha, + doublereal *x, integer *incx, doublereal *y, integer *incy, + doublereal *a, integer *lda) +{ + + + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer info; + static doublereal temp1, temp2; + static integer i, j; + extern logical lsame_(char *, char *); + static integer ix, iy, jx, jy, kx, ky; + extern /* Subroutine */ int xerbla_(char *, integer *); + + +/* Purpose + ======= + + DSYR2 performs the symmetric rank 2 operation + + A := alpha*x*y' + alpha*y*x' + A, + + where alpha is a scalar, x and y are n element vectors and A is an n + + by n symmetric matrix. + + Parameters + ========== + + UPLO - CHARACTER*1. + On entry, UPLO specifies whether the upper or lower + triangular part of the array A is to be referenced as + follows: + + UPLO = 'U' or 'u' Only the upper triangular part of A + is to be referenced. + + UPLO = 'L' or 'l' Only the lower triangular part of A + is to be referenced. + + Unchanged on exit. + + N - INTEGER. + On entry, N specifies the order of the matrix A. + N must be at least zero. + Unchanged on exit. + + ALPHA - DOUBLE PRECISION. + On entry, ALPHA specifies the scalar alpha. + Unchanged on exit. + + X - DOUBLE PRECISION array of dimension at least + ( 1 + ( n - 1 )*abs( INCX ) ). + Before entry, the incremented array X must contain the n + element vector x. + Unchanged on exit. + + INCX - INTEGER. + On entry, INCX specifies the increment for the elements of + X. INCX must not be zero. + Unchanged on exit. + + Y - DOUBLE PRECISION array of dimension at least + ( 1 + ( n - 1 )*abs( INCY ) ). + Before entry, the incremented array Y must contain the n + element vector y. + Unchanged on exit. + + INCY - INTEGER. + On entry, INCY specifies the increment for the elements of + Y. INCY must not be zero. + Unchanged on exit. + + A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). + Before entry with UPLO = 'U' or 'u', the leading n by n + upper triangular part of the array A must contain the upper + + triangular part of the symmetric matrix and the strictly + lower triangular part of A is not referenced. On exit, the + upper triangular part of the array A is overwritten by the + upper triangular part of the updated matrix. + Before entry with UPLO = 'L' or 'l', the leading n by n + lower triangular part of the array A must contain the lower + + triangular part of the symmetric matrix and the strictly + upper triangular part of A is not referenced. On exit, the + lower triangular part of the array A is overwritten by the + lower triangular part of the updated matrix. + + LDA - INTEGER. + On entry, LDA specifies the first dimension of A as declared + + in the calling (sub) program. LDA must be at least + max( 1, n ). + Unchanged on exit. + + + Level 2 Blas routine. + + -- Written on 22-October-1986. + Jack Dongarra, Argonne National Lab. + Jeremy Du Croz, Nag Central Office. + Sven Hammarling, Nag Central Office. + Richard Hanson, Sandia National Labs. + + + + Test the input parameters. + + + Parameter adjustments + Function Body */ +#define X(I) x[(I)-1] +#define Y(I) y[(I)-1] + +#define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] + + info = 0; + if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { + info = 1; + } else if (*n < 0) { + info = 2; + } else if (*incx == 0) { + info = 5; + } else if (*incy == 0) { + info = 7; + } else if (*lda < max(1,*n)) { + info = 9; + } + if (info != 0) { + xerbla_("DSYR2 ", &info); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0 || *alpha == 0.) { + return 0; + } + +/* Set up the start points in X and Y if the increments are not both + + unity. */ + + if (*incx != 1 || *incy != 1) { + if (*incx > 0) { + kx = 1; + } else { + kx = 1 - (*n - 1) * *incx; + } + if (*incy > 0) { + ky = 1; + } else { + ky = 1 - (*n - 1) * *incy; + } + jx = kx; + jy = ky; + } + +/* Start the operations. In this version the elements of A are + accessed sequentially with one pass through the triangular part + of A. */ + + if (lsame_(uplo, "U")) { + +/* Form A when A is stored in the upper triangle. */ + + if (*incx == 1 && *incy == 1) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + if (X(j) != 0. || Y(j) != 0.) { + temp1 = *alpha * Y(j); + temp2 = *alpha * X(j); + i__2 = j; + for (i = 1; i <= j; ++i) { + A(i,j) = A(i,j) + X(i) * temp1 + + Y(i) * temp2; +/* L10: */ + } + } +/* L20: */ + } + } else { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + if (X(jx) != 0. || Y(jy) != 0.) { + temp1 = *alpha * Y(jy); + temp2 = *alpha * X(jx); + ix = kx; + iy = ky; + i__2 = j; + for (i = 1; i <= j; ++i) { + A(i,j) = A(i,j) + X(ix) * temp1 + + Y(iy) * temp2; + ix += *incx; + iy += *incy; +/* L30: */ + } + } + jx += *incx; + jy += *incy; +/* L40: */ + } + } + } else { + +/* Form A when A is stored in the lower triangle. */ + + if (*incx == 1 && *incy == 1) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + if (X(j) != 0. || Y(j) != 0.) { + temp1 = *alpha * Y(j); + temp2 = *alpha * X(j); + i__2 = *n; + for (i = j; i <= *n; ++i) { + A(i,j) = A(i,j) + X(i) * temp1 + + Y(i) * temp2; +/* L50: */ + } + } +/* L60: */ + } + } else { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + if (X(jx) != 0. || Y(jy) != 0.) { + temp1 = *alpha * Y(jy); + temp2 = *alpha * X(jx); + ix = jx; + iy = jy; + i__2 = *n; + for (i = j; i <= *n; ++i) { + A(i,j) = A(i,j) + X(ix) * temp1 + + Y(iy) * temp2; + ix += *incx; + iy += *incy; +/* L70: */ + } + } + jx += *incx; + jy += *incy; +/* L80: */ + } + } + } + + return 0; + +/* End of DSYR2 . */ + +} /* dsyr2_ */ + diff --git a/src/matrix/camblas/dsyr2k.c b/src/matrix/camblas/dsyr2k.c new file mode 100644 index 0000000..01f9192 --- /dev/null +++ b/src/matrix/camblas/dsyr2k.c @@ -0,0 +1,421 @@ + +/* -- translated by f2c (version 19940927). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */ int __IMPEXP__ dsyr2k_(char *uplo, char *trans, integer *n, integer *k, + doublereal *alpha, doublereal *a, integer *lda, doublereal *b, + integer *ldb, doublereal *beta, doublereal *c, integer *ldc) +{ + + + /* System generated locals */ + integer a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, i__1, i__2, + i__3; + + /* Local variables */ + static integer info; + static doublereal temp1, temp2; + static integer i, j, l; + extern logical lsame_(char *, char *); + static integer nrowa; + static logical upper; + extern /* Subroutine */ int xerbla_(char *, integer *); + + +/* Purpose + ======= + + DSYR2K performs one of the symmetric rank 2k operations + + C := alpha*A*B' + alpha*B*A' + beta*C, + + or + + C := alpha*A'*B + alpha*B'*A + beta*C, + + where alpha and beta are scalars, C is an n by n symmetric matrix + + and A and B are n by k matrices in the first case and k by n + + matrices in the second case. + + Parameters + ========== + + UPLO - CHARACTER*1. + On entry, UPLO specifies whether the upper or lower + + triangular part of the array C is to be referenced as + + follows: + + UPLO = 'U' or 'u' Only the upper triangular part of C + + is to be referenced. + + UPLO = 'L' or 'l' Only the lower triangular part of C + + is to be referenced. + + Unchanged on exit. + + TRANS - CHARACTER*1. + On entry, TRANS specifies the operation to be performed as + + follows: + + TRANS = 'N' or 'n' C := alpha*A*B' + alpha*B*A' + + beta*C. + + TRANS = 'T' or 't' C := alpha*A'*B + alpha*B'*A + + beta*C. + + TRANS = 'C' or 'c' C := alpha*A'*B + alpha*B'*A + + beta*C. + + Unchanged on exit. + + N - INTEGER. + On entry, N specifies the order of the matrix C. N must be + + at least zero. + Unchanged on exit. + + K - INTEGER. + On entry with TRANS = 'N' or 'n', K specifies the number + + of columns of the matrices A and B, and on entry with + + TRANS = 'T' or 't' or 'C' or 'c', K specifies the number + + of rows of the matrices A and B. K must be at least zero. + + Unchanged on exit. + + ALPHA - DOUBLE PRECISION. + On entry, ALPHA specifies the scalar alpha. + Unchanged on exit. + + A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is + + k when TRANS = 'N' or 'n', and is n otherwise. + Before entry with TRANS = 'N' or 'n', the leading n by k + + part of the array A must contain the matrix A, otherwise + + the leading k by n part of the array A must contain the + + matrix A. + Unchanged on exit. + + LDA - INTEGER. + On entry, LDA specifies the first dimension of A as declared + + in the calling (sub) program. When TRANS = 'N' or 'n' + + then LDA must be at least max( 1, n ), otherwise LDA must + + be at least max( 1, k ). + Unchanged on exit. + + B - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is + + k when TRANS = 'N' or 'n', and is n otherwise. + Before entry with TRANS = 'N' or 'n', the leading n by k + + part of the array B must contain the matrix B, otherwise + + the leading k by n part of the array B must contain the + + matrix B. + Unchanged on exit. + + LDB - INTEGER. + On entry, LDB specifies the first dimension of B as declared + + in the calling (sub) program. When TRANS = 'N' or 'n' + + then LDB must be at least max( 1, n ), otherwise LDB must + + be at least max( 1, k ). + Unchanged on exit. + + BETA - DOUBLE PRECISION. + On entry, BETA specifies the scalar beta. + Unchanged on exit. + + C - DOUBLE PRECISION array of DIMENSION ( LDC, n ). + Before entry with UPLO = 'U' or 'u', the leading n by n + + upper triangular part of the array C must contain the upper + + triangular part of the symmetric matrix and the strictly + + lower triangular part of C is not referenced. On exit, the + + upper triangular part of the array C is overwritten by the + + upper triangular part of the updated matrix. + Before entry with UPLO = 'L' or 'l', the leading n by n + + lower triangular part of the array C must contain the lower + + triangular part of the symmetric matrix and the strictly + + upper triangular part of C is not referenced. On exit, the + + lower triangular part of the array C is overwritten by the + + lower triangular part of the updated matrix. + + LDC - INTEGER. + On entry, LDC specifies the first dimension of C as declared + + in the calling (sub) program. LDC must be at least + + max( 1, n ). + Unchanged on exit. + + + Level 3 Blas routine. + + + -- Written on 8-February-1989. + Jack Dongarra, Argonne National Laboratory. + Iain Duff, AERE Harwell. + Jeremy Du Croz, Numerical Algorithms Group Ltd. + Sven Hammarling, Numerical Algorithms Group Ltd. + + + + Test the input parameters. + + + Parameter adjustments + Function Body */ + +#define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] +#define B(I,J) b[(I)-1 + ((J)-1)* ( *ldb)] +#define C(I,J) c[(I)-1 + ((J)-1)* ( *ldc)] + + if (lsame_(trans, "N")) { + nrowa = *n; + } else { + nrowa = *k; + } + upper = lsame_(uplo, "U"); + + info = 0; + if (! upper && ! lsame_(uplo, "L")) { + info = 1; + } else if (! lsame_(trans, "N") && ! lsame_(trans, "T") && + ! lsame_(trans, "C")) { + info = 2; + } else if (*n < 0) { + info = 3; + } else if (*k < 0) { + info = 4; + } else if (*lda < max(1,nrowa)) { + info = 7; + } else if (*ldb < max(1,nrowa)) { + info = 9; + } else if (*ldc < max(1,*n)) { + info = 12; + } + if (info != 0) { + xerbla_("DSYR2K", &info); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0 || (*alpha == 0. || *k == 0) && *beta == 1.) { + return 0; + } + +/* And when alpha.eq.zero. */ + + if (*alpha == 0.) { + if (upper) { + if (*beta == 0.) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + i__2 = j; + for (i = 1; i <= j; ++i) { + C(i,j) = 0.; +/* L10: */ + } +/* L20: */ + } + } else { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + i__2 = j; + for (i = 1; i <= j; ++i) { + C(i,j) = *beta * C(i,j); +/* L30: */ + } +/* L40: */ + } + } + } else { + if (*beta == 0.) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + i__2 = *n; + for (i = j; i <= *n; ++i) { + C(i,j) = 0.; +/* L50: */ + } +/* L60: */ + } + } else { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + i__2 = *n; + for (i = j; i <= *n; ++i) { + C(i,j) = *beta * C(i,j); +/* L70: */ + } +/* L80: */ + } + } + } + return 0; + } + +/* Start the operations. */ + + if (lsame_(trans, "N")) { + +/* Form C := alpha*A*B' + alpha*B*A' + C. */ + + if (upper) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + if (*beta == 0.) { + i__2 = j; + for (i = 1; i <= j; ++i) { + C(i,j) = 0.; +/* L90: */ + } + } else if (*beta != 1.) { + i__2 = j; + for (i = 1; i <= j; ++i) { + C(i,j) = *beta * C(i,j); +/* L100: */ + } + } + i__2 = *k; + for (l = 1; l <= *k; ++l) { + if (A(j,l) != 0. || B(j,l) != 0.) { + temp1 = *alpha * B(j,l); + temp2 = *alpha * A(j,l); + i__3 = j; + for (i = 1; i <= j; ++i) { + C(i,j) = C(i,j) + A(i,l) * temp1 + B(i,l) * + temp2; +/* L110: */ + } + } +/* L120: */ + } +/* L130: */ + } + } else { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + if (*beta == 0.) { + i__2 = *n; + for (i = j; i <= *n; ++i) { + C(i,j) = 0.; +/* L140: */ + } + } else if (*beta != 1.) { + i__2 = *n; + for (i = j; i <= *n; ++i) { + C(i,j) = *beta * C(i,j); +/* L150: */ + } + } + i__2 = *k; + for (l = 1; l <= *k; ++l) { + if (A(j,l) != 0. || B(j,l) != 0.) { + temp1 = *alpha * B(j,l); + temp2 = *alpha * A(j,l); + i__3 = *n; + for (i = j; i <= *n; ++i) { + C(i,j) = C(i,j) + A(i,l) * temp1 + B(i,l) * + temp2; +/* L160: */ + } + } +/* L170: */ + } +/* L180: */ + } + } + } else { + +/* Form C := alpha*A'*B + alpha*B'*A + C. */ + + if (upper) { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + i__2 = j; + for (i = 1; i <= j; ++i) { + temp1 = 0.; + temp2 = 0.; + i__3 = *k; + for (l = 1; l <= *k; ++l) { + temp1 += A(l,i) * B(l,j); + temp2 += B(l,i) * A(l,j); +/* L190: */ + } + if (*beta == 0.) { + C(i,j) = *alpha * temp1 + *alpha * temp2; + } else { + C(i,j) = *beta * C(i,j) + * + alpha * temp1 + *alpha * temp2; + } +/* L200: */ + } +/* L210: */ + } + } else { + i__1 = *n; + for (j = 1; j <= *n; ++j) { + i__2 = *n; + for (i = j; i <= *n; ++i) { + temp1 = 0.; + temp2 = 0.; + i__3 = *k; + for (l = 1; l <= *k; ++l) { + temp1 += A(l,i) * B(l,j); + temp2 += B(l,i) * A(l,j); +/* L220: */ + } + if (*beta == 0.) { + C(i,j) = *alpha * temp1 + *alpha * temp2; + } else { + C(i,j) = *beta * C(i,j) + * + alpha * temp1 + *alpha * temp2; + } +/* L230: */ + } +/* L240: */ + } + } + } + + return 0; + +/* End of DSYR2K. */ + +} /* dsyr2k_ */ + diff --git a/src/matrix/camblas/dtrmm.c b/src/matrix/camblas/dtrmm.c new file mode 100644 index 0000000..a1de642 --- /dev/null +++ b/src/matrix/camblas/dtrmm.c @@ -0,0 +1,480 @@ +/* DTRMM.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* DECK DTRMM */ +/* Subroutine */ int __IMPEXP__ dtrmm_(side, uplo, transa, diag, m, n, alpha, a, lda, b, + ldb, side_len, uplo_len, transa_len, diag_len) +char *side, *uplo, *transa, *diag; +integer *m, *n; +doublereal *alpha, *a; +integer *lda; +doublereal *b; +integer *ldb; +ftnlen side_len; +ftnlen uplo_len; +ftnlen transa_len; +ftnlen diag_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3; + + /* Local variables */ + static integer info; + static doublereal temp; + static integer i, j, k; + static logical lside; + extern logical lsame_(); + static integer nrowa; + static logical upper; + extern /* Subroutine */ int xerbla_(); + static logical nounit; + +/* ***BEGIN PROLOGUE DTRMM */ +/* ***PURPOSE Perform one of the matrix-matrix operations. */ +/* ***LIBRARY SLATEC (BLAS) */ +/* ***CATEGORY D1B6 */ +/* ***TYPE DOUBLE PRECISION (STRMM-S, DTRMM-D, CTRMM-C) */ +/* ***KEYWORDS LEVEL 3 BLAS, LINEAR ALGEBRA */ +/* ***AUTHOR Dongarra, J., (ANL) */ +/* Duff, I., (AERE) */ +/* Du Croz, J., (NAG) */ +/* Hammarling, S. (NAG) */ +/* ***DESCRIPTION */ + +/* DTRMM performs one of the matrix-matrix operations */ + +/* B := alpha*op( A )*B, or B := alpha*B*op( A ), */ + +/* where alpha is a scalar, B is an m by n matrix, A is a unit, or +*/ +/* non-unit, upper or lower triangular matrix and op( A ) is one of +*/ + +/* op( A ) = A or op( A ) = A'. */ + +/* Parameters */ +/* ========== */ + +/* SIDE - CHARACTER*1. */ +/* On entry, SIDE specifies whether op( A ) multiplies B from +*/ +/* the left or right as follows: */ + +/* SIDE = 'L' or 'l' B := alpha*op( A )*B. */ + +/* SIDE = 'R' or 'r' B := alpha*B*op( A ). */ + +/* Unchanged on exit. */ + +/* UPLO - CHARACTER*1. */ +/* On entry, UPLO specifies whether the matrix A is an upper or +*/ +/* lower triangular matrix as follows: */ + +/* UPLO = 'U' or 'u' A is an upper triangular matrix. */ + +/* UPLO = 'L' or 'l' A is a lower triangular matrix. */ + +/* Unchanged on exit. */ + +/* TRANSA - CHARACTER*1. */ +/* On entry, TRANSA specifies the form of op( A ) to be used in +*/ +/* the matrix multiplication as follows: */ + +/* TRANSA = 'N' or 'n' op( A ) = A. */ + +/* TRANSA = 'T' or 't' op( A ) = A'. */ + +/* TRANSA = 'C' or 'c' op( A ) = A'. */ + +/* Unchanged on exit. */ + +/* DIAG - CHARACTER*1. */ +/* On entry, DIAG specifies whether or not A is unit triangular +*/ +/* as follows: */ + +/* DIAG = 'U' or 'u' A is assumed to be unit triangular. */ + +/* DIAG = 'N' or 'n' A is not assumed to be unit */ +/* triangular. */ + +/* Unchanged on exit. */ + +/* M - INTEGER. */ +/* On entry, M specifies the number of rows of B. M must be at +*/ +/* least zero. */ +/* Unchanged on exit. */ + +/* N - INTEGER. */ +/* On entry, N specifies the number of columns of B. N must be +*/ +/* at least zero. */ +/* Unchanged on exit. */ + +/* ALPHA - DOUBLE PRECISION. */ +/* On entry, ALPHA specifies the scalar alpha. When alpha is +*/ +/* zero then A is not referenced and B need not be set before +*/ +/* entry. */ +/* Unchanged on exit. */ + +/* A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m +*/ +/* when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. +*/ +/* Before entry with UPLO = 'U' or 'u', the leading k by k +*/ +/* upper triangular part of the array A must contain the upper +*/ +/* triangular matrix and the strictly lower triangular part of +*/ +/* A is not referenced. */ +/* Before entry with UPLO = 'L' or 'l', the leading k by k +*/ +/* lower triangular part of the array A must contain the lower +*/ +/* triangular matrix and the strictly upper triangular part of +*/ +/* A is not referenced. */ +/* Note that when DIAG = 'U' or 'u', the diagonal elements of +*/ +/* A are not referenced either, but are assumed to be unity. +*/ +/* Unchanged on exit. */ + +/* LDA - INTEGER. */ +/* On entry, LDA specifies the first dimension of A as declared +*/ +/* in the calling (sub) program. When SIDE = 'L' or 'l' then +*/ +/* LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' +*/ +/* then LDA must be at least max( 1, n ). */ +/* Unchanged on exit. */ + +/* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ). */ +/* Before entry, the leading m by n part of the array B must +*/ +/* contain the matrix B, and on exit is overwritten by the +*/ +/* transformed matrix. */ + +/* LDB - INTEGER. */ +/* On entry, LDB specifies the first dimension of B as declared +*/ +/* in the calling (sub) program. LDB must be at least +*/ +/* max( 1, m ). */ +/* Unchanged on exit. */ + +/* ***REFERENCES Dongarra, J., Du Croz, J., Duff, I., and Hammarling, S. +*/ +/* A set of level 3 basic linear algebra subprograms. */ +/* ACM TOMS, Vol. 16, No. 1, pp. 1-17, March 1990. */ +/* ***ROUTINES CALLED LSAME, XERBLA */ +/* ***REVISION HISTORY (YYMMDD) */ +/* 890208 DATE WRITTEN */ +/* 910605 Modified to meet SLATEC prologue standards. Only comment */ +/* lines were modified. (BKS) */ +/* ***END PROLOGUE DTRMM */ +/* .. Scalar Arguments .. */ +/* .. Array Arguments .. */ +/* .. External Functions .. */ +/* .. External Subroutines .. */ +/* .. Intrinsic Functions .. */ +/* .. Local Scalars .. */ +/* .. Parameters .. */ +/* ***FIRST EXECUTABLE STATEMENT DTRMM */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + b_dim1 = *ldb; + b_offset = b_dim1 + 1; + b -= b_offset; + + /* Function Body */ + lside = lsame_(side, "L", 1L, 1L); + if (lside) { + nrowa = *m; + } else { + nrowa = *n; + } + nounit = lsame_(diag, "N", 1L, 1L); + upper = lsame_(uplo, "U", 1L, 1L); + + info = 0; + if (! lside && ! lsame_(side, "R", 1L, 1L)) { + info = 1; + } else if (! upper && ! lsame_(uplo, "L", 1L, 1L)) { + info = 2; + } else if (! lsame_(transa, "N", 1L, 1L) && ! lsame_(transa, "T", 1L, 1L) + && ! lsame_(transa, "C", 1L, 1L)) { + info = 3; + } else if (! lsame_(diag, "U", 1L, 1L) && ! lsame_(diag, "N", 1L, 1L)) { + info = 4; + } else if (*m < 0) { + info = 5; + } else if (*n < 0) { + info = 6; + } else if (*lda < max(1,nrowa)) { + info = 9; + } else if (*ldb < max(1,*m)) { + info = 11; + } + if (info != 0) { + xerbla_("DTRMM ", &info, 6L); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0) { + return 0; + } + +/* And when alpha.eq.zero. */ + + if (*alpha == 0.) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = 0.; +/* L10: */ + } +/* L20: */ + } + return 0; + } + +/* Start the operations. */ + + if (lside) { + if (lsame_(transa, "N", 1L, 1L)) { + +/* Form B := alpha*A*B. */ + + if (upper) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (k = 1; k <= i__2; ++k) { + if (b[k + j * b_dim1] != 0.) { + temp = *alpha * b[k + j * b_dim1]; + i__3 = k - 1; + for (i = 1; i <= i__3; ++i) { + b[i + j * b_dim1] += temp * a[i + k * a_dim1]; +/* L30: */ + } + if (nounit) { + temp *= a[k + k * a_dim1]; + } + b[k + j * b_dim1] = temp; + } +/* L40: */ + } +/* L50: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + for (k = *m; k >= 1; --k) { + if (b[k + j * b_dim1] != 0.) { + temp = *alpha * b[k + j * b_dim1]; + b[k + j * b_dim1] = temp; + if (nounit) { + b[k + j * b_dim1] *= a[k + k * a_dim1]; + } + i__2 = *m; + for (i = k + 1; i <= i__2; ++i) { + b[i + j * b_dim1] += temp * a[i + k * a_dim1]; +/* L60: */ + } + } +/* L70: */ + } +/* L80: */ + } + } + } else { + +/* Form B := alpha*B*A'. */ + + if (upper) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + for (i = *m; i >= 1; --i) { + temp = b[i + j * b_dim1]; + if (nounit) { + temp *= a[i + i * a_dim1]; + } + i__2 = i - 1; + for (k = 1; k <= i__2; ++k) { + temp += a[k + i * a_dim1] * b[k + j * b_dim1]; +/* L90: */ + } + b[i + j * b_dim1] = *alpha * temp; +/* L100: */ + } +/* L110: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + temp = b[i + j * b_dim1]; + if (nounit) { + temp *= a[i + i * a_dim1]; + } + i__3 = *m; + for (k = i + 1; k <= i__3; ++k) { + temp += a[k + i * a_dim1] * b[k + j * b_dim1]; +/* L120: */ + } + b[i + j * b_dim1] = *alpha * temp; +/* L130: */ + } +/* L140: */ + } + } + } + } else { + if (lsame_(transa, "N", 1L, 1L)) { + +/* Form B := alpha*B*A. */ + + if (upper) { + for (j = *n; j >= 1; --j) { + temp = *alpha; + if (nounit) { + temp *= a[j + j * a_dim1]; + } + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + b[i + j * b_dim1] = temp * b[i + j * b_dim1]; +/* L150: */ + } + i__1 = j - 1; + for (k = 1; k <= i__1; ++k) { + if (a[k + j * a_dim1] != 0.) { + temp = *alpha * a[k + j * a_dim1]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] += temp * b[i + k * b_dim1]; +/* L160: */ + } + } +/* L170: */ + } +/* L180: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + temp = *alpha; + if (nounit) { + temp *= a[j + j * a_dim1]; + } + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = temp * b[i + j * b_dim1]; +/* L190: */ + } + i__2 = *n; + for (k = j + 1; k <= i__2; ++k) { + if (a[k + j * a_dim1] != 0.) { + temp = *alpha * a[k + j * a_dim1]; + i__3 = *m; + for (i = 1; i <= i__3; ++i) { + b[i + j * b_dim1] += temp * b[i + k * b_dim1]; +/* L200: */ + } + } +/* L210: */ + } +/* L220: */ + } + } + } else { + +/* Form B := alpha*B*A'. */ + + if (upper) { + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + i__2 = k - 1; + for (j = 1; j <= i__2; ++j) { + if (a[j + k * a_dim1] != 0.) { + temp = *alpha * a[j + k * a_dim1]; + i__3 = *m; + for (i = 1; i <= i__3; ++i) { + b[i + j * b_dim1] += temp * b[i + k * b_dim1]; +/* L230: */ + } + } +/* L240: */ + } + temp = *alpha; + if (nounit) { + temp *= a[k + k * a_dim1]; + } + if (temp != 1.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + k * b_dim1] = temp * b[i + k * b_dim1]; +/* L250: */ + } + } +/* L260: */ + } + } else { + for (k = *n; k >= 1; --k) { + i__1 = *n; + for (j = k + 1; j <= i__1; ++j) { + if (a[j + k * a_dim1] != 0.) { + temp = *alpha * a[j + k * a_dim1]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] += temp * b[i + k * b_dim1]; +/* L270: */ + } + } +/* L280: */ + } + temp = *alpha; + if (nounit) { + temp *= a[k + k * a_dim1]; + } + if (temp != 1.) { + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + b[i + k * b_dim1] = temp * b[i + k * b_dim1]; +/* L290: */ + } + } +/* L300: */ + } + } + } + } + + return 0; + +/* End of DTRMM . */ + +} /* dtrmm_ */ + diff --git a/src/matrix/camblas/dtrmv.c b/src/matrix/camblas/dtrmv.c new file mode 100644 index 0000000..31939c3 --- /dev/null +++ b/src/matrix/camblas/dtrmv.c @@ -0,0 +1,360 @@ +/* DTRMV.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* DECK DTRMV */ +/* Subroutine */ int __IMPEXP__ dtrmv_(uplo, trans, diag, n, a, lda, x, incx, uplo_len, + trans_len, diag_len) +char *uplo, *trans, *diag; +integer *n; +doublereal *a; +integer *lda; +doublereal *x; +integer *incx; +ftnlen uplo_len; +ftnlen trans_len; +ftnlen diag_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer info; + static doublereal temp; + static integer i, j; + extern logical lsame_(); + static integer ix, jx, kx; + extern /* Subroutine */ int xerbla_(); + static logical nounit; + +/* ***BEGIN PROLOGUE DTRMV */ +/* ***PURPOSE Perform one of the matrix-vector operations. */ +/* ***LIBRARY SLATEC (BLAS) */ +/* ***CATEGORY D1B4 */ +/* ***TYPE DOUBLE PRECISION (STRMV-S, DTRMV-D, CTRMV-C) */ +/* ***KEYWORDS LEVEL 2 BLAS, LINEAR ALGEBRA */ +/* ***AUTHOR Dongarra, J. J., (ANL) */ +/* Du Croz, J., (NAG) */ +/* Hammarling, S., (NAG) */ +/* Hanson, R. J., (SNLA) */ +/* ***DESCRIPTION */ + +/* DTRMV performs one of the matrix-vector operations */ + +/* x := A*x, or x := A'*x, */ + +/* where x is an n element vector and A is an n by n unit, or non-unit, +*/ +/* upper or lower triangular matrix. */ + +/* Parameters */ +/* ========== */ + +/* UPLO - CHARACTER*1. */ +/* On entry, UPLO specifies whether the matrix is an upper or */ +/* lower triangular matrix as follows: */ + +/* UPLO = 'U' or 'u' A is an upper triangular matrix. */ + +/* UPLO = 'L' or 'l' A is a lower triangular matrix. */ + +/* Unchanged on exit. */ + +/* TRANS - CHARACTER*1. */ +/* On entry, TRANS specifies the operation to be performed as */ +/* follows: */ + +/* TRANS = 'N' or 'n' x := A*x. */ + +/* TRANS = 'T' or 't' x := A'*x. */ + +/* TRANS = 'C' or 'c' x := A'*x. */ + +/* Unchanged on exit. */ + +/* DIAG - CHARACTER*1. */ +/* On entry, DIAG specifies whether or not A is unit */ +/* triangular as follows: */ + +/* DIAG = 'U' or 'u' A is assumed to be unit triangular. */ + +/* DIAG = 'N' or 'n' A is not assumed to be unit */ +/* triangular. */ + +/* Unchanged on exit. */ + +/* N - INTEGER. */ +/* On entry, N specifies the order of the matrix A. */ +/* N must be at least zero. */ +/* Unchanged on exit. */ + +/* A - DOUBLE PRECISION array of DIMENSION ( LDA, n). */ +/* Before entry with UPLO = 'U' or 'u', the leading n by n */ +/* upper triangular part of the array A must contain the upper +*/ +/* triangular matrix and the strictly lower triangular part of +*/ +/* A is not referenced. */ +/* Before entry with UPLO = 'L' or 'l', the leading n by n */ +/* lower triangular part of the array A must contain the lower +*/ +/* triangular matrix and the strictly upper triangular part of +*/ +/* A is not referenced. */ +/* Note that when DIAG = 'U' or 'u', the diagonal elements of +*/ +/* A are not referenced either, but are assumed to be unity. */ +/* Unchanged on exit. */ + +/* LDA - INTEGER. */ +/* On entry, LDA specifies the first dimension of A as declared +*/ +/* in the calling (sub) program. LDA must be at least */ +/* max( 1, n ). */ +/* Unchanged on exit. */ + +/* X - DOUBLE PRECISION array of dimension at least */ +/* ( 1 + ( n - 1 )*abs( INCX ) ). */ +/* Before entry, the incremented array X must contain the n */ +/* element vector x. On exit, X is overwritten with the */ +/* tranformed vector x. */ + +/* INCX - INTEGER. */ +/* On entry, INCX specifies the increment for the elements of */ +/* X. INCX must not be zero. */ +/* Unchanged on exit. */ + +/* ***REFERENCES Dongarra, J. J., Du Croz, J., Hammarling, S., and */ +/* Hanson, R. J. An extended set of Fortran basic linear +*/ +/* algebra subprograms. ACM TOMS, Vol. 14, No. 1, */ +/* pp. 1-17, March 1988. */ +/* ***ROUTINES CALLED LSAME, XERBLA */ +/* ***REVISION HISTORY (YYMMDD) */ +/* 861022 DATE WRITTEN */ +/* 910605 Modified to meet SLATEC prologue standards. Only comment */ +/* lines were modified. (BKS) */ +/* ***END PROLOGUE DTRMV */ +/* .. Scalar Arguments .. */ +/* .. Array Arguments .. */ +/* .. Parameters .. */ +/* .. Local Scalars .. */ +/* .. External Functions .. */ +/* .. External Subroutines .. */ +/* .. Intrinsic Functions .. */ +/* ***FIRST EXECUTABLE STATEMENT DTRMV */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --x; + + /* Function Body */ + info = 0; + if (! lsame_(uplo, "U", 1L, 1L) && ! lsame_(uplo, "L", 1L, 1L)) { + info = 1; + } else if (! lsame_(trans, "N", 1L, 1L) && ! lsame_(trans, "T", 1L, 1L) && + ! lsame_(trans, "C", 1L, 1L)) { + info = 2; + } else if (! lsame_(diag, "U", 1L, 1L) && ! lsame_(diag, "N", 1L, 1L)) { + info = 3; + } else if (*n < 0) { + info = 4; + } else if (*lda < max(1,*n)) { + info = 6; + } else if (*incx == 0) { + info = 8; + } + if (info != 0) { + xerbla_("DTRMV ", &info, 6L); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0) { + return 0; + } + + nounit = lsame_(diag, "N", 1L, 1L); + +/* Set up the start point in X if the increment is not unity. This */ +/* will be ( N - 1 )*INCX too small for descending loops. */ + + if (*incx <= 0) { + kx = 1 - (*n - 1) * *incx; + } else if (*incx != 1) { + kx = 1; + } + +/* Start the operations. In this version the elements of A are */ +/* accessed sequentially with one pass through A. */ + + if (lsame_(trans, "N", 1L, 1L)) { + +/* Form x := A*x. */ + + if (lsame_(uplo, "U", 1L, 1L)) { + if (*incx == 1) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (x[j] != 0.) { + temp = x[j]; + i__2 = j - 1; + for (i = 1; i <= i__2; ++i) { + x[i] += temp * a[i + j * a_dim1]; +/* L10: */ + } + if (nounit) { + x[j] *= a[j + j * a_dim1]; + } + } +/* L20: */ + } + } else { + jx = kx; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (x[jx] != 0.) { + temp = x[jx]; + ix = kx; + i__2 = j - 1; + for (i = 1; i <= i__2; ++i) { + x[ix] += temp * a[i + j * a_dim1]; + ix += *incx; +/* L30: */ + } + if (nounit) { + x[jx] *= a[j + j * a_dim1]; + } + } + jx += *incx; +/* L40: */ + } + } + } else { + if (*incx == 1) { + for (j = *n; j >= 1; --j) { + if (x[j] != 0.) { + temp = x[j]; + i__1 = j + 1; + for (i = *n; i >= i__1; --i) { + x[i] += temp * a[i + j * a_dim1]; +/* L50: */ + } + if (nounit) { + x[j] *= a[j + j * a_dim1]; + } + } +/* L60: */ + } + } else { + kx += (*n - 1) * *incx; + jx = kx; + for (j = *n; j >= 1; --j) { + if (x[jx] != 0.) { + temp = x[jx]; + ix = kx; + i__1 = j + 1; + for (i = *n; i >= i__1; --i) { + x[ix] += temp * a[i + j * a_dim1]; + ix -= *incx; +/* L70: */ + } + if (nounit) { + x[jx] *= a[j + j * a_dim1]; + } + } + jx -= *incx; +/* L80: */ + } + } + } + } else { + +/* Form x := A'*x. */ + + if (lsame_(uplo, "U", 1L, 1L)) { + if (*incx == 1) { + for (j = *n; j >= 1; --j) { + temp = x[j]; + if (nounit) { + temp *= a[j + j * a_dim1]; + } + for (i = j - 1; i >= 1; --i) { + temp += a[i + j * a_dim1] * x[i]; +/* L90: */ + } + x[j] = temp; +/* L100: */ + } + } else { + jx = kx + (*n - 1) * *incx; + for (j = *n; j >= 1; --j) { + temp = x[jx]; + ix = jx; + if (nounit) { + temp *= a[j + j * a_dim1]; + } + for (i = j - 1; i >= 1; --i) { + ix -= *incx; + temp += a[i + j * a_dim1] * x[ix]; +/* L110: */ + } + x[jx] = temp; + jx -= *incx; +/* L120: */ + } + } + } else { + if (*incx == 1) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + temp = x[j]; + if (nounit) { + temp *= a[j + j * a_dim1]; + } + i__2 = *n; + for (i = j + 1; i <= i__2; ++i) { + temp += a[i + j * a_dim1] * x[i]; +/* L130: */ + } + x[j] = temp; +/* L140: */ + } + } else { + jx = kx; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + temp = x[jx]; + ix = jx; + if (nounit) { + temp *= a[j + j * a_dim1]; + } + i__2 = *n; + for (i = j + 1; i <= i__2; ++i) { + ix += *incx; + temp += a[i + j * a_dim1] * x[ix]; +/* L150: */ + } + x[jx] = temp; + jx += *incx; +/* L160: */ + } + } + } + } + + return 0; + +/* End of DTRMV . */ + +} /* dtrmv_ */ + diff --git a/src/matrix/camblas/f2c.h b/src/matrix/camblas/f2c.h new file mode 100644 index 0000000..b044eb3 --- /dev/null +++ b/src/matrix/camblas/f2c.h @@ -0,0 +1,214 @@ +/* f2c.h -- Standard Fortran to C header file */ + +/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." + + - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ + +#ifndef F2C_INCLUDE +#define F2C_INCLUDE + +typedef long int integer; +typedef char *address; +typedef short int shortint; +typedef float real; +typedef double doublereal; +typedef struct { real r, i; } complex; +typedef struct { doublereal r, i; } doublecomplex; +typedef long int logical; +typedef short int shortlogical; +typedef char logical1; +typedef char integer1; +/* typedef long long longint; */ /* system-dependent */ + +#define TRUE_ (1) +#define FALSE_ (0) + +/* Extern is for use with -E */ +#ifndef Extern +#define Extern extern +#endif + +/* I/O stuff */ + +#ifdef f2c_i2 +/* for -i2 */ +typedef short flag; +typedef short ftnlen; +typedef short ftnint; +#else +typedef long int flag; +typedef long int ftnlen; +typedef long int ftnint; +#endif + +/*external read, write*/ +typedef struct +{ flag cierr; + ftnint ciunit; + flag ciend; + char *cifmt; + ftnint cirec; +} cilist; + +/*internal read, write*/ +typedef struct +{ flag icierr; + char *iciunit; + flag iciend; + char *icifmt; + ftnint icirlen; + ftnint icirnum; +} icilist; + +/*open*/ +typedef struct +{ flag oerr; + ftnint ounit; + char *ofnm; + ftnlen ofnmlen; + char *osta; + char *oacc; + char *ofm; + ftnint orl; + char *oblnk; +} olist; + +/*close*/ +typedef struct +{ flag cerr; + ftnint cunit; + char *csta; +} cllist; + +/*rewind, backspace, endfile*/ +typedef struct +{ flag aerr; + ftnint aunit; +} alist; + +/* inquire */ +typedef struct +{ flag inerr; + ftnint inunit; + char *infile; + ftnlen infilen; + ftnint *inex; /*parameters in standard's order*/ + ftnint *inopen; + ftnint *innum; + ftnint *innamed; + char *inname; + ftnlen innamlen; + char *inacc; + ftnlen inacclen; + char *inseq; + ftnlen inseqlen; + char *indir; + ftnlen indirlen; + char *infmt; + ftnlen infmtlen; + char *inform; + ftnint informlen; + char *inunf; + ftnlen inunflen; + ftnint *inrecl; + ftnint *innrec; + char *inblank; + ftnlen inblanklen; +} inlist; + +#define VOID void + +union Multitype { /* for multiple entry points */ + integer1 g; + shortint h; + integer i; + /* longint j; */ + real r; + doublereal d; + complex c; + doublecomplex z; + }; + +typedef union Multitype Multitype; + +/*typedef long int Long;*/ /* No longer used; formerly in Namelist */ + +struct Vardesc { /* for Namelist */ + char *name; + char *addr; + ftnlen *dims; + int type; + }; +typedef struct Vardesc Vardesc; + +struct Namelist { + char *name; + Vardesc **vars; + int nvars; + }; +typedef struct Namelist Namelist; + +#define abs(x) ((x) >= 0 ? (x) : -(x)) +#define dabs(x) (doublereal)abs(x) +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#define dmin(a,b) (doublereal)min(a,b) +#define dmax(a,b) (doublereal)max(a,b) + +/* procedure parameter types for -A and -C++ */ + +#define F2C_proc_par_types 1 +#ifdef __cplusplus +typedef int /* Unknown procedure type */ (*U_fp)(...); +typedef shortint (*J_fp)(...); +typedef integer (*I_fp)(...); +typedef real (*R_fp)(...); +typedef doublereal (*D_fp)(...), (*E_fp)(...); +typedef /* Complex */ VOID (*C_fp)(...); +typedef /* Double Complex */ VOID (*Z_fp)(...); +typedef logical (*L_fp)(...); +typedef shortlogical (*K_fp)(...); +typedef /* Character */ VOID (*H_fp)(...); +typedef /* Subroutine */ int (*S_fp)(...); +#else +typedef int /* Unknown procedure type */ (*U_fp)(); +typedef shortint (*J_fp)(); +typedef integer (*I_fp)(); +typedef real (*R_fp)(); +typedef doublereal (*D_fp)(), (*E_fp)(); +typedef /* Complex */ VOID (*C_fp)(); +typedef /* Double Complex */ VOID (*Z_fp)(); +typedef logical (*L_fp)(); +typedef shortlogical (*K_fp)(); +typedef /* Character */ VOID (*H_fp)(); +typedef /* Subroutine */ int (*S_fp)(); +#endif +/* E_fp is for real functions when -R is not specified */ +typedef VOID C_f; /* complex function */ +typedef VOID H_f; /* character function */ +typedef VOID Z_f; /* double complex function */ +typedef doublereal E_f; /* real function with -R not specified */ + +/* undef any lower-case symbols that your C compiler predefines, e.g.: */ + +#ifndef Skip_f2c_Undefs +#undef cray +#undef gcos +#undef mc68010 +#undef mc68020 +#undef mips +#undef pdp11 +#undef sgi +#undef sparc +#undef sun +#undef sun2 +#undef sun3 +#undef sun4 +#undef u370 +#undef u3b +#undef u3b2 +#undef u3b5 +#undef unix +#undef vax +#endif +#endif diff --git a/src/matrix/camblas/ilaenv.c b/src/matrix/camblas/ilaenv.c new file mode 100644 index 0000000..342d1d6 --- /dev/null +++ b/src/matrix/camblas/ilaenv.c @@ -0,0 +1,573 @@ +/* ILAENV.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +integer __IMPEXP__ ilaenv_(ispec, name, opts, n1, n2, n3, n4, name_len, opts_len) +integer *ispec; +char *name, *opts; +integer *n1, *n2, *n3, *n4; +ftnlen name_len; +ftnlen opts_len; +{ + /* System generated locals */ + integer ret_val; + + /* Builtin functions */ + /* Subroutine */ int s_copy(); + integer s_cmp(); + + /* Local variables */ + static integer i; + static logical cname, sname; + static integer nbmin; + static char c1[1], c2[2], c3[3], c4[2]; + static integer ic, nb, iz, nx; + static char subnam[6]; + + +/* -- LAPACK auxiliary routine (preliminary version) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* February 20, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* ILAENV is called from the LAPACK routines to choose problem-dependent +*/ +/* parameters for the local environment. See ISPEC for a description of +*/ +/* the parameters. */ + +/* This version provides a set of parameters which should give good, */ +/* but not optimal, performance on many of the currently available */ +/* computers. Users are encouraged to modify this subroutine to set */ +/* the tuning parameters for their particular machine using the option */ +/* and problem size information in the arguments. */ + +/* This routine will not function correctly if it is converted to all */ +/* lower case. Converting it to all upper case is allowed. */ + +/* Arguments */ +/* ========= */ + +/* ISPEC (input) INTEGER */ +/* Specifies the parameter to be returned as the value of */ +/* ILAENV. */ +/* = 1: the optimal blocksize; if this value is 1, an unblocked +*/ +/* algorithm will give the best performance. */ +/* = 2: the minimum block size for which the block routine */ +/* should be used; if the usable block size is less than */ +/* this value, an unblocked routine should be used. */ +/* = 3: the crossover point (in a block routine, for N less */ +/* than this value, an unblocked routine should be used) */ +/* = 4: the number of shifts, used in the nonsymmetric */ +/* eigenvalue routines */ +/* = 5: the minimum column dimension for blocking to be used; */ +/* rectangular blocks must have dimension at least k by m, +*/ +/* where k is given by ILAENV(2,...) and m by ILAENV(5,...) +*/ +/* = 6: the crossover point for the SVD (when reducing an m by n +*/ +/* matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds +*/ +/* this value, a QR factorization is used first to reduce */ +/* the matrix to a triangular form.) */ +/* = 7: the number of processors */ +/* = 8: the crossover point for the multishift QR and QZ methods +*/ +/* for nonsymmetric eigenvalue problems. */ + +/* NAME (input) CHARACTER*(*) */ +/* The name of the calling subroutine, in either upper case or */ +/* lower case. */ + +/* OPTS (input) CHARACTER*(*) */ +/* The character options to the subroutine NAME, concatenated */ +/* into a single character string. For example, UPLO = 'U', */ +/* TRANS = 'T', and DIAG = 'N' for a triangular routine would */ +/* be specified as OPTS = 'UTN'. */ + +/* N1 (input) INTEGER */ +/* N2 (input) INTEGER */ +/* N3 (input) INTEGER */ +/* N4 (input) INTEGER */ +/* Problem dimensions for the subroutine NAME; these may not all +*/ +/* be required. */ + +/* (ILAENV) (output) INTEGER */ +/* >= 0: the value of the parameter specified by ISPEC */ +/* < 0: if ILAENV = -k, the k-th argument had an illegal value. +*/ + +/* Further Details */ +/* =============== */ + +/* The following conventions have been used when calling ILAENV from the +*/ +/* LAPACK routines: */ +/* 1) OPTS is a concatenation of all of the character options to */ +/* subroutine NAME, in the same order that they appear in the */ +/* argument list for NAME, even if they are not used in determining +*/ +/* the value of the parameter specified by ISPEC. */ +/* 2) The problem dimensions N1, N2, N3, N4 are specified in the order +*/ +/* that they appear in the argument list for NAME. N1 is used */ +/* first, N2 second, and so on, and unused problem dimensions are */ +/* passed a value of -1. */ +/* 3) The parameter value returned by ILAENV is checked for validity in +*/ +/* the calling subroutine. For example, ILAENV is used to retrieve +*/ +/* the optimal blocksize for STRTRI as follows: */ + +/* NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 ) */ +/* IF( NB.LE.1 ) NB = MAX( 1, N ) */ + +/* ===================================================================== +*/ + +/* .. Local Scalars .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + switch ((int)*ispec) { + case 1: goto L100; + case 2: goto L100; + case 3: goto L100; + case 4: goto L400; + case 5: goto L500; + case 6: goto L600; + case 7: goto L700; + case 8: goto L800; + } + +/* Invalid value for ISPEC */ + + ret_val = -1; + return ret_val; + +L100: + +/* Convert NAME to upper case if the first character is lower case. */ + + ret_val = 1; + s_copy(subnam, name, 6L, name_len); + ic = *(unsigned char *)subnam; + iz = 'Z'; + if (iz == 90 || iz == 122) { + +/* ASCII character set */ + + if (ic >= 97 && ic <= 122) { + *(unsigned char *)subnam = (char) (ic - 32); + for (i = 2; i <= 6; ++i) { + ic = *(unsigned char *)&subnam[i - 1]; + if (ic >= 97 && ic <= 122) { + *(unsigned char *)&subnam[i - 1] = (char) (ic - 32); + } +/* L10: */ + } + } + + } else if (iz == 233 || iz == 169) { + +/* EBCDIC character set */ + + if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && + ic <= 169) { + *(unsigned char *)subnam = (char) (ic + 64); + for (i = 2; i <= 6; ++i) { + ic = *(unsigned char *)&subnam[i - 1]; + if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= + 162 && ic <= 169) { + *(unsigned char *)&subnam[i - 1] = (char) (ic + 64); + } +/* L20: */ + } + } + + } else if (iz == 218 || iz == 250) { + +/* Prime machines: ASCII+128 */ + + if (ic >= 225 && ic <= 250) { + *(unsigned char *)subnam = (char) (ic - 32); + for (i = 2; i <= 6; ++i) { + ic = *(unsigned char *)&subnam[i - 1]; + if (ic >= 225 && ic <= 250) { + *(unsigned char *)&subnam[i - 1] = (char) (ic - 32); + } +/* L30: */ + } + } + } + + *(unsigned char *)c1 = *(unsigned char *)subnam; + sname = *(unsigned char *)c1 == 'S' || *(unsigned char *)c1 == 'D'; + cname = *(unsigned char *)c1 == 'C' || *(unsigned char *)c1 == 'Z'; + if (! (cname || sname)) { + return ret_val; + } + s_copy(c2, subnam + 1, 2L, 2L); + s_copy(c3, subnam + 3, 3L, 3L); + s_copy(c4, c3 + 1, 2L, 2L); + + switch ((int)*ispec) { + case 1: goto L110; + case 2: goto L200; + case 3: goto L300; + } + +L110: + +/* ISPEC = 1: block size */ + +/* In these examples, separate code is provided for setting NB for */ +/* real and complex. We assume that NB will take the same value in */ +/* single or double precision. */ + + nb = 1; + + if (s_cmp(c2, "GE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } else if (s_cmp(c3, "QRF", 3L, 3L) == 0 || s_cmp(c3, "RQF", 3L, 3L) + == 0 || s_cmp(c3, "LQF", 3L, 3L) == 0 || s_cmp(c3, "QLF", 3L, + 3L) == 0) { + if (sname) { + nb = 32; + } else { + nb = 32; + } + } else if (s_cmp(c3, "HRD", 3L, 3L) == 0) { + if (sname) { + nb = 32; + } else { + nb = 32; + } + } else if (s_cmp(c3, "BRD", 3L, 3L) == 0) { + if (sname) { + nb = 32; + } else { + nb = 32; + } + } else if (s_cmp(c3, "TRI", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (s_cmp(c2, "PO", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (s_cmp(c2, "SY", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } else if (sname && s_cmp(c3, "TRD", 3L, 3L) == 0) { + nb = 1; + } else if (sname && s_cmp(c3, "GST", 3L, 3L) == 0) { + nb = 64; + } + } else if (cname && s_cmp(c2, "HE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + nb = 64; + } else if (s_cmp(c3, "TRD", 3L, 3L) == 0) { + nb = 1; + } else if (s_cmp(c3, "GST", 3L, 3L) == 0) { + nb = 64; + } + } else if (sname && s_cmp(c2, "OR", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } + } else if (cname && s_cmp(c2, "UN", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } + } else if (s_cmp(c2, "GB", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + if (*n4 <= 64) { + nb = 1; + } else { + nb = 32; + } + } else { + if (*n4 <= 64) { + nb = 1; + } else { + nb = 32; + } + } + } + } else if (s_cmp(c2, "PB", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + if (*n2 <= 64) { + nb = 1; + } else { + nb = 32; + } + } else { + if (*n2 <= 64) { + nb = 1; + } else { + nb = 32; + } + } + } + } else if (s_cmp(c2, "TR", 2L, 2L) == 0) { + if (s_cmp(c3, "TRI", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (s_cmp(c2, "LA", 2L, 2L) == 0) { + if (s_cmp(c3, "UUM", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (sname && s_cmp(c2, "ST", 2L, 2L) == 0) { + if (s_cmp(c3, "EBZ", 3L, 3L) == 0) { + nb = 1; + } + } + ret_val = nb; + return ret_val; + +L200: + +/* ISPEC = 2: minimum block size */ + + nbmin = 2; + if (s_cmp(c2, "GE", 2L, 2L) == 0) { + if (s_cmp(c3, "QRF", 3L, 3L) == 0 || s_cmp(c3, "RQF", 3L, 3L) == 0 || + s_cmp(c3, "LQF", 3L, 3L) == 0 || s_cmp(c3, "QLF", 3L, 3L) == + 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (s_cmp(c3, "HRD", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (s_cmp(c3, "BRD", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (s_cmp(c3, "TRI", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } + } else if (s_cmp(c2, "SY", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (sname && s_cmp(c3, "TRD", 3L, 3L) == 0) { + nbmin = 2; + } + } else if (cname && s_cmp(c2, "HE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRD", 3L, 3L) == 0) { + nbmin = 2; + } + } else if (sname && s_cmp(c2, "OR", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } + } else if (cname && s_cmp(c2, "UN", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } + } + ret_val = nbmin; + return ret_val; + +L300: + +/* ISPEC = 3: crossover point */ + + nx = 0; + if (s_cmp(c2, "GE", 2L, 2L) == 0) { + if (s_cmp(c3, "QRF", 3L, 3L) == 0 || s_cmp(c3, "RQF", 3L, 3L) == 0 || + s_cmp(c3, "LQF", 3L, 3L) == 0 || s_cmp(c3, "QLF", 3L, 3L) == + 0) { + if (sname) { + nx = 128; + } else { + nx = 128; + } + } else if (s_cmp(c3, "HRD", 3L, 3L) == 0) { + if (sname) { + nx = 128; + } else { + nx = 128; + } + } else if (s_cmp(c3, "BRD", 3L, 3L) == 0) { + if (sname) { + nx = 128; + } else { + nx = 128; + } + } + } else if (s_cmp(c2, "SY", 2L, 2L) == 0) { + if (sname && s_cmp(c3, "TRD", 3L, 3L) == 0) { + nx = 1; + } + } else if (cname && s_cmp(c2, "HE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRD", 3L, 3L) == 0) { + nx = 1; + } + } else if (sname && s_cmp(c2, "OR", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nx = 128; + } + } + } else if (cname && s_cmp(c2, "UN", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nx = 128; + } + } + } + ret_val = nx; + return ret_val; + +L400: + +/* ISPEC = 4: number of shifts (used by xHSEQR) */ + + ret_val = 6; + return ret_val; + +L500: + +/* ISPEC = 5: minimum column dimension (not used) */ + + ret_val = 2; + return ret_val; + +L600: + +/* ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) */ + + ret_val = (integer) ((real) min(*n1,*n2) * (float)1.6); + return ret_val; + +L700: + +/* ISPEC = 7: number of processors (not used) */ + + ret_val = 1; + return ret_val; + +L800: + +/* ISPEC = 8: crossover point for multishift (used by xHSEQR) */ + + ret_val = 50; + return ret_val; + +/* End of ILAENV */ + +} /* ilaenv_ */ + diff --git a/src/matrix/camblas/lsame.c b/src/matrix/camblas/lsame.c new file mode 100644 index 0000000..9e35485 --- /dev/null +++ b/src/matrix/camblas/lsame.c @@ -0,0 +1,116 @@ +/* LSAME.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +logical __IMPEXP__ lsame_(ca, cb, ca_len, cb_len) +char *ca, *cb; +ftnlen ca_len; +ftnlen cb_len; +{ + /* System generated locals */ + logical ret_val; + + /* Local variables */ + static integer inta, intb, zcode; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* February 29, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* LSAME returns .TRUE. if CA is the same letter as CB regardless of */ +/* case. */ + +/* Arguments */ +/* ========= */ + +/* CA (input) CHARACTER*1 */ +/* CB (input) CHARACTER*1 */ +/* CA and CB specify the single characters to be compared. */ + +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test if the characters are equal */ + + ret_val = *(unsigned char *)ca == *(unsigned char *)cb; + if (ret_val) { + return ret_val; + } + +/* Now test for equivalence if both characters are alphabetic. */ + + zcode = 'Z'; + +/* Use 'Z' rather than 'A' so that ASCII can be detected on Prime */ +/* machines, on which ICHAR returns a value with bit 8 set. */ +/* ICHAR('A') on Prime machines returns 193 which is the same as */ +/* ICHAR('A') on an EBCDIC machine. */ + + inta = *(unsigned char *)ca; + intb = *(unsigned char *)cb; + + if (zcode == 90 || zcode == 122) { + +/* ASCII is assumed - ZCODE is the ASCII code of either lower o +r */ +/* upper case 'Z'. */ + + if (inta >= 97 && inta <= 122) { + inta += -32; + } + if (intb >= 97 && intb <= 122) { + intb += -32; + } + + } else if (zcode == 233 || zcode == 169) { + +/* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower + or */ +/* upper case 'Z'. */ + + if (inta >= 129 && inta <= 137 || inta >= 145 && inta <= 153 || inta + >= 162 && inta <= 169) { + inta += 64; + } + if (intb >= 129 && intb <= 137 || intb >= 145 && intb <= 153 || intb + >= 162 && intb <= 169) { + intb += 64; + } + + } else if (zcode == 218 || zcode == 250) { + +/* ASCII is assumed, on Prime machines - ZCODE is the ASCII cod +e */ +/* plus 128 of either lower or upper case 'Z'. */ + + if (inta >= 225 && inta <= 250) { + inta += -32; + } + if (intb >= 225 && intb <= 250) { + intb += -32; + } + } + ret_val = inta == intb; + +/* RETURN */ + +/* End of LSAME */ + + return ret_val; +} /* lsame_ */ + diff --git a/src/matrix/camblas/s_cmp.c b/src/matrix/camblas/s_cmp.c new file mode 100644 index 0000000..b891a6c --- /dev/null +++ b/src/matrix/camblas/s_cmp.c @@ -0,0 +1,44 @@ +#include "f2c.h" + +/* compare two strings */ + +#ifdef KR_headers +integer s_cmp(a0, b0, la, lb) char *a0, *b0; ftnlen la, lb; +#else +integer s_cmp(char *a0, char *b0, ftnlen la, ftnlen lb) +#endif +{ +register unsigned char *a, *aend, *b, *bend; +a = (unsigned char *)a0; +b = (unsigned char *)b0; +aend = a + la; +bend = b + lb; + +if(la <= lb) + { + while(a < aend) + if(*a != *b) + return( *a - *b ); + else + { ++a; ++b; } + + while(b < bend) + if(*b != ' ') + return( ' ' - *b ); + else ++b; + } + +else + { + while(b < bend) + if(*a == *b) + { ++a; ++b; } + else + return( *a - *b ); + while(a < aend) + if(*a != ' ') + return(*a - ' '); + else ++a; + } +return(0); +} diff --git a/src/matrix/camblas/s_copy.c b/src/matrix/camblas/s_copy.c new file mode 100644 index 0000000..13f40a5 --- /dev/null +++ b/src/matrix/camblas/s_copy.c @@ -0,0 +1,27 @@ +#include "f2c.h" + +/* assign strings: a = b */ + +#ifdef KR_headers +VOID s_copy(a, b, la, lb) register char *a, *b; ftnlen la, lb; +#else +void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb) +#endif +{ +register char *aend, *bend; + +aend = a + la; + +if(la <= lb) + while(a < aend) + *a++ = *b++; + +else + { + bend = b + lb; + while(b < bend) + *a++ = *b++; + while(a < aend) + *a++ = ' '; + } +} diff --git a/src/matrix/camblas/xerbla.c b/src/matrix/camblas/xerbla.c new file mode 100644 index 0000000..aea78c1 --- /dev/null +++ b/src/matrix/camblas/xerbla.c @@ -0,0 +1,55 @@ +/* XERBLA.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "cblasimpexp.h" + +/* Subroutine */ int __IMPEXP__ xerbla_(srname, info, srname_len) +char *srname; +integer *info; +ftnlen srname_len; +{ +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* XERBLA is an error handler for the Level 2 BLAS routines. */ + +/* It is called by the Level 2 BLAS routines if an input parameter is */ +/* invalid. */ + +/* Installers should consider modifying the STOP statement in order to */ +/* call system-specific exception-handling facilities. */ + +/* Parameters */ +/* ========== */ + +/* SRNAME - CHARACTER*6. */ +/* On entry, SRNAME specifies the name of the routine which */ +/* called XERBLA. */ + +/* INFO - INTEGER. */ +/* On entry, INFO specifies the position of the invalid */ +/* parameter in the parameter-list of the calling routine. */ + + +/* Auxiliary routine for Level 2 Blas. */ + +/* Written on 20-July-1986. */ + +/* .. Executable Statements .. */ + +/* WRITE (*,99999) SRNAME, INFO */ + +/* STOP */ + + +/* End of XERBLA. */ + +/* L99999: */ +} /* xerbla_ */ + diff --git a/src/matrix/camlapack/CVS/Entries b/src/matrix/camlapack/CVS/Entries new file mode 100644 index 0000000..2d27e62 --- /dev/null +++ b/src/matrix/camlapack/CVS/Entries @@ -0,0 +1,31 @@ +/Jamfile/1.3/Tue Dec 9 00:59:55 2003// +/camlaimpexp.h/1.1/Tue Mar 25 20:02:59 2003// +/d_lg10.c/1.1/Tue Mar 25 20:02:59 2003// +/d_sign.c/1.1/Tue Mar 25 20:02:59 2003// +/dgecon.c/1.1/Tue Mar 25 20:02:59 2003// +/dgeequ.c/1.1/Tue Mar 25 20:02:59 2003// +/dgerfs.c/1.1/Tue Mar 25 20:03:00 2003// +/dgesvx.c/1.1/Tue Mar 25 20:03:00 2003// +/dgetf2.c/1.1/Tue Mar 25 20:03:00 2003// +/dgetrf.c/1.1/Tue Mar 25 20:03:00 2003// +/dgetrs.c/1.1/Tue Mar 25 20:03:00 2003// +/dlabad.c/1.1/Tue Mar 25 20:03:00 2003// +/dlacon.c/1.1/Tue Mar 25 20:03:00 2003// +/dlacpy.c/1.1/Tue Mar 25 20:03:00 2003// +/dlamch.c/1.1/Tue Mar 25 20:03:00 2003// +/dlange.c/1.1/Tue Mar 25 20:03:03 2003// +/dlaqge.c/1.1/Tue Mar 25 20:03:03 2003// +/dlassq.c/1.1/Tue Mar 25 20:03:04 2003// +/dlaswp.c/1.1/Tue Mar 25 20:03:05 2003// +/dlatrs.c/1.1/Tue Mar 25 20:03:06 2003// +/drscl.c/1.1/Tue Mar 25 20:03:06 2003// +/dtrsm.c/1.1/Tue Mar 25 20:03:06 2003// +/dtrsv.c/1.1/Tue Mar 25 20:03:06 2003// +/f2c.h/1.1/Tue Mar 25 20:03:06 2003// +/i_dnnt.c/1.1/Tue Mar 25 20:03:06 2003// +/idamax.c/1.1/Tue Mar 25 20:03:06 2003// +/ilaenv.c/1.1/Tue Mar 25 20:03:10 2003// +/pow_di.c/1.1/Tue Mar 25 20:03:10 2003// +/s_cmp.c/1.1/Tue Mar 25 20:03:12 2003// +/s_copy.c/1.1/Tue Mar 25 20:03:14 2003// +D diff --git a/src/matrix/camlapack/CVS/Repository b/src/matrix/camlapack/CVS/Repository new file mode 100644 index 0000000..f5371b1 --- /dev/null +++ b/src/matrix/camlapack/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/matrix/camlapack diff --git a/src/matrix/camlapack/CVS/Root b/src/matrix/camlapack/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/matrix/camlapack/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/matrix/camlapack/Jamfile b/src/matrix/camlapack/Jamfile new file mode 100644 index 0000000..e8c7456 --- /dev/null +++ b/src/matrix/camlapack/Jamfile @@ -0,0 +1,12 @@ +########################################### +# Jamfile for Camlapack routines +# +# Author: xb70 (Troy B. Jones) +# Revision: 6/29/2003 +########################################### + +# Location of this jamfile +SubDir OPENSESSAME_ROOT src matrix camlapack ; + +# Compile the following sources into objects +Objects d_lg10.c d_sign.c dgecon.c dgeequ.c dgerfs.c dgetf2.c dgetrf.c dgetrs.c dlabad.c dlacon.c dlacpy.c dlamch.c dlange.c dlaqge.c dlassq.c dlaswp.c dlatrs.c drscl.c dtrsm.c dtrsv.c i_dnnt.c idamax.c ilaenv.c pow_di.c dgesvx.c ; diff --git a/src/matrix/camlapack/camlaimpexp.h b/src/matrix/camlapack/camlaimpexp.h new file mode 100644 index 0000000..62238e2 --- /dev/null +++ b/src/matrix/camlapack/camlaimpexp.h @@ -0,0 +1,6 @@ +#ifdef __EXPORT_CAMLAPACK__ +#define __IMPEXP__ __declspec(dllexport) +#else +#define __IMPEXP__ +#endif + diff --git a/src/matrix/camlapack/d_lg10.c b/src/matrix/camlapack/d_lg10.c new file mode 100644 index 0000000..9f4a089 --- /dev/null +++ b/src/matrix/camlapack/d_lg10.c @@ -0,0 +1,15 @@ +#include "f2c.h" + +#define log10e 0.43429448190325182765 + +#ifdef KR_headers +double log(); +double d_lg10(x) doublereal *x; +#else +#undef abs +#include "math.h" +double d_lg10(doublereal *x) +#endif +{ +return( log10e * log(*x) ); +} diff --git a/src/matrix/camlapack/d_sign.c b/src/matrix/camlapack/d_sign.c new file mode 100644 index 0000000..61a6cf8 --- /dev/null +++ b/src/matrix/camlapack/d_sign.c @@ -0,0 +1,12 @@ +#include "f2c.h" + +#ifdef KR_headers +double d_sign(a,b) doublereal *a, *b; +#else +double d_sign(doublereal *a, doublereal *b) +#endif +{ +double x; +x = (*a >= 0 ? *a : - *a); +return( *b >= 0 ? x : -x); +} diff --git a/src/matrix/camlapack/dgecon.c b/src/matrix/camlapack/dgecon.c new file mode 100644 index 0000000..0361189 --- /dev/null +++ b/src/matrix/camlapack/dgecon.c @@ -0,0 +1,225 @@ +/* DGECON.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; + +/* Subroutine */ int dgecon_(norm, n, a, lda, anorm, rcond, work, iwork, info, + norm_len) +char *norm; +integer *n; +doublereal *a; +integer *lda; +doublereal *anorm, *rcond, *work; +integer *iwork, *info; +ftnlen norm_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1; + doublereal d__1; + + /* Local variables */ + static integer kase, kase1; + static doublereal scale; + extern logical lsame_(); + extern /* Subroutine */ int drscl_(); + extern doublereal dlamch_(); + static doublereal sl; + static integer ix; + extern /* Subroutine */ int dlacon_(); + extern integer idamax_(); + static doublereal su; + extern /* Subroutine */ int xerbla_(); + static doublereal ainvnm; + extern /* Subroutine */ int dlatrs_(); + static logical onenrm; + static char normin[1]; + static doublereal smlnum; + + +/* -- LAPACK routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* February 29, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGECON estimates the reciprocal of the condition number of a general +*/ +/* real matrix A, in either the 1-norm or the infinity-norm, using */ +/* the LU factorization computed by DGETRF. */ + +/* An estimate is obtained for norm(inv(A)), and the reciprocal of the */ +/* condition number is computed as */ +/* RCOND = 1 / ( norm(A) * norm(inv(A)) ). */ + +/* Arguments */ +/* ========= */ + +/* NORM (input) CHARACTER*1 */ +/* Specifies whether the 1-norm condition number or the */ +/* infinity-norm condition number is required: */ +/* = '1' or 'O': 1-norm; */ +/* = 'I': Infinity-norm. */ + +/* N (input) INTEGER */ +/* The order of the matrix A. N >= 0. */ + +/* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ +/* The factors L and U from the factorization A = P*L*U */ +/* as computed by DGETRF. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,N). */ + +/* ANORM (input) DOUBLE PRECISION */ +/* If NORM = '1' or 'O', the 1-norm of the original matrix A. */ +/* If NORM = 'I', the infinity-norm of the original matrix A. */ + +/* RCOND (output) DOUBLE PRECISION */ +/* The reciprocal of the condition number of the matrix A, */ +/* computed as RCOND = 1/(norm(A) * norm(inv(A))). */ + +/* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */ + +/* IWORK (workspace) INTEGER array, dimension (N) */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -i, the i-th argument had an illegal value */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --work; + --iwork; + + /* Function Body */ + *info = 0; + onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O", 1L, 1L); + if (! onenrm && ! lsame_(norm, "I", 1L, 1L)) { + *info = -1; + } else if (*n < 0) { + *info = -2; + } else if (*lda < max(1,*n)) { + *info = -4; + } else if (*anorm < 0.) { + *info = -5; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DGECON", &i__1, 6L); + return 0; + } + +/* Quick return if possible */ + + *rcond = 0.; + if (*n == 0) { + *rcond = 1.; + return 0; + } else if (*anorm == 0.) { + return 0; + } + + smlnum = dlamch_("Safe minimum", 12L); + +/* Estimate the norm of inv(A). */ + + ainvnm = 0.; + *(unsigned char *)normin = 'N'; + if (onenrm) { + kase1 = 1; + } else { + kase1 = 2; + } + kase = 0; +L10: + dlacon_(n, &work[*n + 1], &work[1], &iwork[1], &ainvnm, &kase); + if (kase != 0) { + if (kase == kase1) { + +/* Multiply by inv(L). */ + + dlatrs_("Lower", "No transpose", "Unit", normin, n, &a[a_offset], + lda, &work[1], &sl, &work[(*n << 1) + 1], info, 5L, 12L, + 4L, 1L); + +/* Multiply by inv(U). */ + + dlatrs_("Upper", "No transpose", "Non-unit", normin, n, &a[ + a_offset], lda, &work[1], &su, &work[*n * 3 + 1], info, + 5L, 12L, 8L, 1L); + } else { + +/* Multiply by inv(U'). */ + + dlatrs_("Upper", "Transpose", "Non-unit", normin, n, &a[a_offset], + lda, &work[1], &su, &work[*n * 3 + 1], info, 5L, 9L, 8L, + 1L); + +/* Multiply by inv(L'). */ + + dlatrs_("Lower", "Transpose", "Unit", normin, n, &a[a_offset], + lda, &work[1], &sl, &work[(*n << 1) + 1], info, 5L, 9L, + 4L, 1L); + } + +/* Divide X by 1/(SL*SU) if doing so will not cause overflow. +*/ + + scale = sl * su; + *(unsigned char *)normin = 'Y'; + if (scale != 1.) { + ix = idamax_(n, &work[1], &c__1); + if (scale < (d__1 = work[ix], abs(d__1)) * smlnum || scale == 0.) + { + goto L20; + } + drscl_(n, &scale, &work[1], &c__1); + } + goto L10; + } + +/* Compute the estimate of the reciprocal condition number. */ + + if (ainvnm != 0.) { + *rcond = 1. / ainvnm / *anorm; + } + +L20: + return 0; + +/* End of DGECON */ + +} /* dgecon_ */ + diff --git a/src/matrix/camlapack/dgeequ.c b/src/matrix/camlapack/dgeequ.c new file mode 100644 index 0000000..132dbfb --- /dev/null +++ b/src/matrix/camlapack/dgeequ.c @@ -0,0 +1,295 @@ +/* DGEEQU.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Subroutine */ int dgeequ_(m, n, a, lda, r, c, rowcnd, colcnd, amax, info) +integer *m, *n; +doublereal *a; +integer *lda; +doublereal *r, *c, *rowcnd, *colcnd, *amax; +integer *info; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + doublereal d__1, d__2, d__3; + + /* Local variables */ + static integer i, j; + static doublereal rcmin, rcmax; + extern doublereal dlamch_(); + extern /* Subroutine */ int xerbla_(); + static doublereal bignum, smlnum; + + +/* -- LAPACK routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* March 31, 1993 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGEEQU computes row and column scalings intended to equilibrate an */ +/* M-by-N matrix A and reduce its condition number. R returns the row */ +/* scale factors and C the column scale factors, chosen to try to make */ +/* the largest entry in each row and column of the matrix B with */ +/* elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. */ + +/* R(i) and C(j) are restricted to be between SMLNUM = smallest safe */ +/* number and BIGNUM = largest safe number. Use of these scaling */ +/* factors is not guaranteed to reduce the condition number of A but */ +/* works well in practice. */ + +/* Arguments */ +/* ========= */ + +/* M (input) INTEGER */ +/* The number of rows of the matrix A. M >= 0. */ + +/* N (input) INTEGER */ +/* The number of columns of the matrix A. N >= 0. */ + +/* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ +/* The M-by-N matrix whose equilibration factors are */ +/* to be computed. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,M). */ + +/* R (output) DOUBLE PRECISION array, dimension (M) */ +/* If INFO = 0 or INFO > M, R contains the row scale factors */ +/* for A. */ + +/* C (output) DOUBLE PRECISION array, dimension (N) */ +/* If INFO = 0, C contains the column scale factors for A. */ + +/* ROWCND (output) DOUBLE PRECISION */ +/* If INFO = 0 or INFO > M, ROWCND contains the ratio of the */ +/* smallest R(i) to the largest R(i). If ROWCND >= 0.1 and */ +/* AMAX is neither too large nor too small, it is not worth */ +/* scaling by R. */ + +/* COLCND (output) DOUBLE PRECISION */ +/* If INFO = 0, COLCND contains the ratio of the smallest */ +/* C(i) to the largest C(i). If COLCND >= 0.1, it is not */ +/* worth scaling by C. */ + +/* AMAX (output) DOUBLE PRECISION */ +/* Absolute value of largest matrix element. If AMAX is very */ +/* close to overflow or very close to underflow, the matrix */ +/* should be scaled. */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -i, the i-th argument had an illegal value */ +/* > 0: if INFO = i, and i is */ +/* <= M: the i-th row of A is exactly zero */ +/* > M: the (i-M)-th column of A is exactly zero */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --r; + --c; + + /* Function Body */ + *info = 0; + if (*m < 0) { + *info = -1; + } else if (*n < 0) { + *info = -2; + } else if (*lda < max(1,*m)) { + *info = -4; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DGEEQU", &i__1, 6L); + return 0; + } + +/* Quick return if possible */ + + if (*m == 0 || *n == 0) { + *rowcnd = 1.; + *colcnd = 1.; + *amax = 0.; + return 0; + } + +/* Get machine constants. */ + + smlnum = dlamch_("S", 1L); + bignum = 1. / smlnum; + +/* Compute row scale factors. */ + + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + r[i] = 0.; +/* L10: */ + } + +/* Find the maximum element in each row. */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { +/* Computing MAX */ + d__2 = r[i], d__3 = (d__1 = a[i + j * a_dim1], abs(d__1)); + r[i] = max(d__2,d__3); +/* L20: */ + } +/* L30: */ + } + +/* Find the maximum and minimum scale factors. */ + + rcmin = bignum; + rcmax = 0.; + i__1 = *m; + for (i = 1; i <= i__1; ++i) { +/* Computing MAX */ + d__1 = rcmax, d__2 = r[i]; + rcmax = max(d__1,d__2); +/* Computing MIN */ + d__1 = rcmin, d__2 = r[i]; + rcmin = min(d__1,d__2); +/* L40: */ + } + *amax = rcmax; + + if (rcmin == 0.) { + +/* Find the first zero scale factor and return an error code. +*/ + + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + if (r[i] == 0.) { + *info = i; + return 0; + } +/* L50: */ + } + } else { + +/* Invert the scale factors. */ + + i__1 = *m; + for (i = 1; i <= i__1; ++i) { +/* Computing MIN */ +/* Computing MAX */ + d__2 = r[i]; + d__1 = max(d__2,smlnum); + r[i] = 1. / min(d__1,bignum); +/* L60: */ + } + +/* Compute ROWCND = min(R(I)) / max(R(I)) */ + + *rowcnd = max(rcmin,smlnum) / min(rcmax,bignum); + } + +/* Compute column scale factors */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + c[j] = 0.; +/* L70: */ + } + +/* Find the maximum element in each column, */ +/* assuming the row scaling computed above. */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { +/* Computing MAX */ + d__2 = c[j], d__3 = (d__1 = a[i + j * a_dim1], abs(d__1)) * r[i]; + c[j] = max(d__2,d__3); +/* L80: */ + } +/* L90: */ + } + +/* Find the maximum and minimum scale factors. */ + + rcmin = bignum; + rcmax = 0.; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { +/* Computing MIN */ + d__1 = rcmin, d__2 = c[j]; + rcmin = min(d__1,d__2); +/* Computing MAX */ + d__1 = rcmax, d__2 = c[j]; + rcmax = max(d__1,d__2); +/* L100: */ + } + + if (rcmin == 0.) { + +/* Find the first zero scale factor and return an error code. +*/ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (c[j] == 0.) { + *info = *m + j; + return 0; + } +/* L110: */ + } + } else { + +/* Invert the scale factors. */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { +/* Computing MIN */ +/* Computing MAX */ + d__2 = c[j]; + d__1 = max(d__2,smlnum); + c[j] = 1. / min(d__1,bignum); +/* L120: */ + } + +/* Compute COLCND = min(C(J)) / max(C(J)) */ + + *colcnd = max(rcmin,smlnum) / min(rcmax,bignum); + } + + return 0; + +/* End of DGEEQU */ + +} /* dgeequ_ */ + diff --git a/src/matrix/camlapack/dgerfs.c b/src/matrix/camlapack/dgerfs.c new file mode 100644 index 0000000..d024368 --- /dev/null +++ b/src/matrix/camlapack/dgerfs.c @@ -0,0 +1,426 @@ +/* DGERFS.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; +static doublereal c_b15 = -1.; +static doublereal c_b17 = 1.; + +/* Subroutine */ int dgerfs_(trans, n, nrhs, a, lda, af, ldaf, ipiv, b, ldb, + x, ldx, ferr, berr, work, iwork, info, trans_len) +char *trans; +integer *n, *nrhs; +doublereal *a; +integer *lda; +doublereal *af; +integer *ldaf, *ipiv; +doublereal *b; +integer *ldb; +doublereal *x; +integer *ldx; +doublereal *ferr, *berr, *work; +integer *iwork, *info; +ftnlen trans_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, x_dim1, + x_offset, i__1, i__2, i__3; + doublereal d__1, d__2, d__3; + + /* Local variables */ + static integer kase; + static doublereal safe1, safe2; + static integer i, j, k; + static doublereal s; + extern logical lsame_(); + extern /* Subroutine */ int dgemv_(), dcopy_(), daxpy_(); + static integer count; + extern doublereal dlamch_(); + extern /* Subroutine */ int dlacon_(); + static doublereal xk; + static integer nz; + static doublereal safmin; + extern /* Subroutine */ int xerbla_(), dgetrs_(); + static logical notran; + static char transt[1]; + static doublereal lstres, eps; + + +/* -- LAPACK routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* March 31, 1993 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGERFS improves the computed solution to a system of linear */ +/* equations and provides error bounds and backward error estimates for +*/ +/* the solution. */ + +/* Arguments */ +/* ========= */ + +/* TRANS (input) CHARACTER*1 */ +/* Specifies the form of the system of equations: */ +/* = 'N': A * X = B (No transpose) */ +/* = 'T': A**T * X = B (Transpose) */ +/* = 'C': A**H * X = B (Conjugate transpose = Transpose) */ + +/* N (input) INTEGER */ +/* The order of the matrix A. N >= 0. */ + +/* NRHS (input) INTEGER */ +/* The number of right hand sides, i.e., the number of columns */ +/* of the matrices B and X. NRHS >= 0. */ + +/* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ +/* The original N-by-N matrix A. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,N). */ + +/* AF (input) DOUBLE PRECISION array, dimension (LDAF,N) */ +/* The factors L and U from the factorization A = P*L*U */ +/* as computed by DGETRF. */ + +/* LDAF (input) INTEGER */ +/* The leading dimension of the array AF. LDAF >= max(1,N). */ + +/* IPIV (input) INTEGER array, dimension (N) */ +/* The pivot indices from DGETRF; for 1<=i<=N, row i of the */ +/* matrix was interchanged with row IPIV(i). */ + +/* B (input) DOUBLE PRECISION array, dimension (LDB,NRHS) */ +/* The right hand side matrix B. */ + +/* LDB (input) INTEGER */ +/* The leading dimension of the array B. LDB >= max(1,N). */ + +/* X (input/output) DOUBLE PRECISION array, dimension (LDX,NRHS) */ +/* On entry, the solution matrix X, as computed by DGETRS. */ +/* On exit, the improved solution matrix X. */ + +/* LDX (input) INTEGER */ +/* The leading dimension of the array X. LDX >= max(1,N). */ + +/* FERR (output) DOUBLE PRECISION array, dimension (NRHS) */ +/* The estimated forward error bounds for each solution vector */ +/* X(j) (the j-th column of the solution matrix X). */ +/* If XTRUE is the true solution, FERR(j) bounds the magnitude */ +/* of the largest entry in (X(j) - XTRUE) divided by */ +/* the magnitude of the largest entry in X(j). The quality of */ +/* the error bound depends on the quality of the estimate of */ +/* norm(inv(A)) computed in the code; if the estimate of */ +/* norm(inv(A)) is accurate, the error bound is guaranteed. */ + +/* BERR (output) DOUBLE PRECISION array, dimension (NRHS) */ +/* The componentwise relative backward error of each solution */ +/* vector X(j) (i.e., the smallest relative change in */ +/* any entry of A or B that makes X(j) an exact solution). */ + +/* WORK (workspace) DOUBLE PRECISION array, dimension (3*N) */ + +/* IWORK (workspace) INTEGER array, dimension (N) */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -i, the i-th argument had an illegal value */ + +/* Internal Parameters */ +/* =================== */ + +/* ITMAX is the maximum number of steps of iterative refinement. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + af_dim1 = *ldaf; + af_offset = af_dim1 + 1; + af -= af_offset; + --ipiv; + b_dim1 = *ldb; + b_offset = b_dim1 + 1; + b -= b_offset; + x_dim1 = *ldx; + x_offset = x_dim1 + 1; + x -= x_offset; + --ferr; + --berr; + --work; + --iwork; + + /* Function Body */ + *info = 0; + notran = lsame_(trans, "N", 1L, 1L); + if (! notran && ! lsame_(trans, "T", 1L, 1L) && ! lsame_(trans, "C", 1L, + 1L)) { + *info = -1; + } else if (*n < 0) { + *info = -2; + } else if (*nrhs < 0) { + *info = -3; + } else if (*lda < max(1,*n)) { + *info = -5; + } else if (*ldaf < max(1,*n)) { + *info = -7; + } else if (*ldb < max(1,*n)) { + *info = -10; + } else if (*ldx < max(1,*n)) { + *info = -12; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DGERFS", &i__1, 6L); + return 0; + } + +/* Quick return if possible */ + + if (*n == 0 || *nrhs == 0) { + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + ferr[j] = 0.; + berr[j] = 0.; +/* L10: */ + } + return 0; + } + + if (notran) { + *(unsigned char *)transt = 'T'; + } else { + *(unsigned char *)transt = 'N'; + } + +/* NZ = maximum number of nonzero entries in each row of A, plus 1 */ + + nz = *n + 1; + eps = dlamch_("Epsilon", 7L); + safmin = dlamch_("Safe minimum", 12L); + safe1 = nz * safmin; + safe2 = safe1 / eps; + +/* Do for each right hand side */ + + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + + count = 1; + lstres = 3.; +L20: + +/* Loop until stopping criterion is satisfied. */ + +/* Compute residual R = B - op(A) * X, */ +/* where op(A) = A, A**T, or A**H, depending on TRANS. */ + + dcopy_(n, &b[j * b_dim1 + 1], &c__1, &work[*n + 1], &c__1); + dgemv_(trans, n, n, &c_b15, &a[a_offset], lda, &x[j * x_dim1 + 1], & + c__1, &c_b17, &work[*n + 1], &c__1, 1L); + +/* Compute componentwise relative backward error from formula +*/ + +/* max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) */ + +/* where abs(Z) is the componentwise absolute value of the matr +ix */ +/* or vector Z. If the i-th component of the denominator is le +ss */ +/* than SAFE2, then SAFE1 is added to the i-th components of th +e */ +/* numerator and denominator before dividing. */ + + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + work[i] = (d__1 = b[i + j * b_dim1], abs(d__1)); +/* L30: */ + } + +/* Compute abs(op(A))*abs(X) + abs(B). */ + + if (notran) { + i__2 = *n; + for (k = 1; k <= i__2; ++k) { + xk = (d__1 = x[k + j * x_dim1], abs(d__1)); + i__3 = *n; + for (i = 1; i <= i__3; ++i) { + work[i] += (d__1 = a[i + k * a_dim1], abs(d__1)) * xk; +/* L40: */ + } +/* L50: */ + } + } else { + i__2 = *n; + for (k = 1; k <= i__2; ++k) { + s = 0.; + i__3 = *n; + for (i = 1; i <= i__3; ++i) { + s += (d__1 = a[i + k * a_dim1], abs(d__1)) * (d__2 = x[i + + j * x_dim1], abs(d__2)); +/* L60: */ + } + work[k] += s; +/* L70: */ + } + } + s = 0.; + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + if (work[i] > safe2) { +/* Computing MAX */ + d__2 = s, d__3 = (d__1 = work[*n + i], abs(d__1)) / work[i]; + s = max(d__2,d__3); + } else { +/* Computing MAX */ + d__2 = s, d__3 = ((d__1 = work[*n + i], abs(d__1)) + safe1) / + (work[i] + safe1); + s = max(d__2,d__3); + } +/* L80: */ + } + berr[j] = s; + +/* Test stopping criterion. Continue iterating if */ +/* 1) The residual BERR(J) is larger than machine epsilon, a +nd */ +/* 2) BERR(J) decreased by at least a factor of 2 during the + */ +/* last iteration, and */ +/* 3) At most ITMAX iterations tried. */ + + if (berr[j] > eps && berr[j] * 2. <= lstres && count <= 5) { + +/* Update solution and try again. */ + + dgetrs_(trans, n, &c__1, &af[af_offset], ldaf, &ipiv[1], &work[*n + + 1], n, info, 1L); + daxpy_(n, &c_b17, &work[*n + 1], &c__1, &x[j * x_dim1 + 1], &c__1) + ; + lstres = berr[j]; + ++count; + goto L20; + } + +/* Bound error from formula */ + +/* norm(X - XTRUE) / norm(X) .le. FERR = */ +/* norm( abs(inv(op(A)))* */ +/* ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X +) */ + +/* where */ +/* norm(Z) is the magnitude of the largest component of Z */ +/* inv(op(A)) is the inverse of op(A) */ +/* abs(Z) is the componentwise absolute value of the matrix o +r */ +/* vector Z */ +/* NZ is the maximum number of nonzeros in any row of A, plus + 1 */ +/* EPS is machine epsilon */ + +/* The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B +)) */ +/* is incremented by SAFE1 if the i-th component of */ +/* abs(op(A))*abs(X) + abs(B) is less than SAFE2. */ + +/* Use DLACON to estimate the infinity-norm of the matrix */ +/* inv(op(A)) * diag(W), */ +/* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */ + + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + if (work[i] > safe2) { + work[i] = (d__1 = work[*n + i], abs(d__1)) + nz * eps * work[ + i]; + } else { + work[i] = (d__1 = work[*n + i], abs(d__1)) + nz * eps * work[ + i] + safe1; + } +/* L90: */ + } + + kase = 0; +L100: + dlacon_(n, &work[(*n << 1) + 1], &work[*n + 1], &iwork[1], &ferr[j], & + kase); + if (kase != 0) { + if (kase == 1) { + +/* Multiply by diag(W)*inv(op(A)**T). */ + + dgetrs_(transt, n, &c__1, &af[af_offset], ldaf, &ipiv[1], & + work[*n + 1], n, info, 1L); + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + work[*n + i] = work[i] * work[*n + i]; +/* L110: */ + } + } else { + +/* Multiply by inv(op(A))*diag(W). */ + + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + work[*n + i] = work[i] * work[*n + i]; +/* L120: */ + } + dgetrs_(trans, n, &c__1, &af[af_offset], ldaf, &ipiv[1], & + work[*n + 1], n, info, 1L); + } + goto L100; + } + +/* Normalize error. */ + + lstres = 0.; + i__2 = *n; + for (i = 1; i <= i__2; ++i) { +/* Computing MAX */ + d__2 = lstres, d__3 = (d__1 = x[i + j * x_dim1], abs(d__1)); + lstres = max(d__2,d__3); +/* L130: */ + } + if (lstres != 0.) { + ferr[j] /= lstres; + } + +/* L140: */ + } + + return 0; + +/* End of DGERFS */ + +} /* dgerfs_ */ + diff --git a/src/matrix/camlapack/dgesvx.c b/src/matrix/camlapack/dgesvx.c new file mode 100644 index 0000000..2c9192b --- /dev/null +++ b/src/matrix/camlapack/dgesvx.c @@ -0,0 +1,564 @@ +/* DGESVX.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" +#include "camlaimpexp.h" + +/* Subroutine */ int __IMPEXP__ dgesvx_(fact, trans, n, nrhs, a, lda, af, ldaf, ipiv, + equed, r, c, b, ldb, x, ldx, rcond, ferr, berr, work, iwork, info, + fact_len, trans_len, equed_len) +char *fact, *trans; +integer *n, *nrhs; +doublereal *a; +integer *lda; +doublereal *af; +integer *ldaf, *ipiv; +char *equed; +doublereal *r, *c, *b; +integer *ldb; +doublereal *x; +integer *ldx; +doublereal *rcond, *ferr, *berr, *work; +integer *iwork, *info; +ftnlen fact_len; +ftnlen trans_len; +ftnlen equed_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, x_dim1, + x_offset, i__1, i__2; + doublereal d__1, d__2; + + /* Local variables */ + static doublereal amax; + static char norm[1]; + static integer i, j; + extern logical lsame_(); + static doublereal rcmin, rcmax, anorm; + static logical equil; + extern doublereal dlamch_(), dlange_(); + extern /* Subroutine */ int dlaqge_(), dgecon_(); + static doublereal colcnd; + static logical nofact; + extern /* Subroutine */ int dgeequ_(), dgerfs_(), dgetrf_(), dlacpy_(), + xerbla_(); + static doublereal bignum; + static integer infequ; + static logical colequ; + extern /* Subroutine */ int dgetrs_(); + static doublereal rowcnd; + static logical notran; + static doublereal smlnum; + static logical rowequ; + + +/* -- LAPACK driver routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* March 31, 1993 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGESVX uses the LU factorization to compute the solution to a real */ +/* system of linear equations */ +/* A * X = B, */ +/* where A is an N-by-N matrix and X and B are N-by-NRHS matrices. */ + +/* Error bounds on the solution and a condition estimate are also */ +/* provided. */ + +/* Description */ +/* =========== */ + +/* The following steps are performed: */ + +/* 1. If FACT = 'E', real scaling factors are computed to equilibrate */ +/* the system: */ +/* TRANS = 'N': diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B +*/ +/* TRANS = 'T': (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B +*/ +/* TRANS = 'C': (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B +*/ +/* Whether or not the system will be equilibrated depends on the */ +/* scaling of the matrix A, but if equilibration is used, A is */ +/* overwritten by diag(R)*A*diag(C) and B by diag(R)*B (if TRANS='N') +*/ +/* or diag(C)*B (if TRANS = 'T' or 'C'). */ + +/* 2. If FACT = 'N' or 'E', the LU decomposition is used to factor the */ +/* matrix A (after equilibration if FACT = 'E') as */ +/* A = P * L * U, */ +/* where P is a permutation matrix, L is a unit lower triangular */ +/* matrix, and U is upper triangular. */ + +/* 3. The factored form of A is used to estimate the condition number */ +/* of the matrix A. If the reciprocal of the condition number is */ +/* less than machine precision, steps 4-6 are skipped. */ + +/* 4. The system of equations is solved for X using the factored form */ +/* of A. */ + +/* 5. Iterative refinement is applied to improve the computed solution */ +/* matrix and calculate error bounds and backward error estimates */ +/* for it. */ + +/* 6. If FACT = 'E' and equilibration was used, the matrix X is */ +/* premultiplied by diag(C) (if TRANS = 'N') or diag(R) (if */ +/* TRANS = 'T' or 'C') so that it solves the original system */ +/* before equilibration. */ + +/* Arguments */ +/* ========= */ + +/* FACT (input) CHARACTER*1 */ +/* Specifies whether or not the factored form of the matrix A is +*/ +/* supplied on entry, and if not, whether the matrix A should be +*/ +/* equilibrated before it is factored. */ +/* = 'F': On entry, AF and IPIV contain the factored form of A. +*/ +/* If EQUED is not 'N', the matrix A has been */ +/* equilibrated with scaling factors given by R and C. */ +/* A, AF, and IPIV are not modified. */ +/* = 'N': The matrix A will be copied to AF and factored. */ +/* = 'E': The matrix A will be equilibrated if necessary, then +*/ +/* copied to AF and factored. */ + +/* TRANS (input) CHARACTER*1 */ +/* Specifies the form of the system of equations: */ +/* = 'N': A * X = B (No transpose) */ +/* = 'T': A**T * X = B (Transpose) */ +/* = 'C': A**H * X = B (Transpose) */ + +/* N (input) INTEGER */ +/* The number of linear equations, i.e., the order of the */ +/* matrix A. N >= 0. */ + +/* NRHS (input) INTEGER */ +/* The number of right-hand sides, i.e., the number of columns */ +/* of the matrices B and X. NRHS >= 0. */ + +/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */ +/* On entry, the N-by-N matrix A. If FACT = 'F' and EQUED is */ +/* not 'N', then A must have been equilibrated by the scaling */ +/* factors in R and/or C. A is not modified if FACT = 'F' or */ +/* 'N', or if FACT = 'E' and EQUED = 'N' on exit. */ + +/* On exit, if EQUED .ne. 'N', A is scaled as follows: */ +/* EQUED = 'R': A := diag(R) * A */ +/* EQUED = 'C': A := A * diag(C) */ +/* EQUED = 'B': A := diag(R) * A * diag(C). */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,N). */ + +/* AF (input or output) DOUBLE PRECISION array, dimension (LDAF,N) +*/ +/* If FACT = 'F', then AF is an input argument and on entry */ +/* contains the factors L and U from the factorization */ +/* A = P*L*U as computed by DGETRF. If EQUED .ne. 'N', then */ +/* AF is the factored form of the equilibrated matrix A. */ + +/* If FACT = 'N', then AF is an output argument and on exit */ +/* returns the factors L and U from the factorization A = P*L*U +*/ +/* of the original matrix A. */ + +/* If FACT = 'E', then AF is an output argument and on exit */ +/* returns the factors L and U from the factorization A = P*L*U +*/ +/* of the equilibrated matrix A (see the description of A for */ +/* the form of the equilibrated matrix). */ + +/* LDAF (input) INTEGER */ +/* The leading dimension of the array AF. LDAF >= max(1,N). */ + +/* IPIV (input or output) INTEGER array, dimension (N) */ +/* If FACT = 'F', then IPIV is an input argument and on entry */ +/* contains the pivot indices from the factorization A = P*L*U */ +/* as computed by DGETRF; row i of the matrix was interchanged */ +/* with row IPIV(i). */ + +/* If FACT = 'N', then IPIV is an output argument and on exit */ +/* contains the pivot indices from the factorization A = P*L*U */ +/* of the original matrix A. */ + +/* If FACT = 'E', then IPIV is an output argument and on exit */ +/* contains the pivot indices from the factorization A = P*L*U */ +/* of the equilibrated matrix A. */ + +/* EQUED (input/output) CHARACTER*1 */ +/* Specifies the form of equilibration that was done. */ +/* = 'N': No equilibration (always true if FACT = 'N'). */ +/* = 'R': Row equilibration, i.e., A has been premultiplied by +*/ +/* diag(R). */ +/* = 'C': Column equilibration, i.e., A has been postmultiplied +*/ +/* by diag(C). */ +/* = 'B': Both row and column equilibration, i.e., A has been */ +/* replaced by diag(R) * A * diag(C). */ +/* EQUED is an input variable if FACT = 'F'; otherwise, it is an +*/ +/* output variable. */ + +/* R (input/output) DOUBLE PRECISION array, dimension (N) */ +/* The row scale factors for A. If EQUED = 'R' or 'B', A is */ +/* multiplied on the left by diag(R); if EQUED = 'N' or 'C', R */ +/* is not accessed. R is an input variable if FACT = 'F'; */ +/* otherwise, R is an output variable. If FACT = 'F' and */ +/* EQUED = 'R' or 'B', each element of R must be positive. */ + +/* C (input/output) DOUBLE PRECISION array, dimension (N) */ +/* The column scale factors for A. If EQUED = 'C' or 'B', A is +*/ +/* multiplied on the right by diag(C); if EQUED = 'N' or 'R', C +*/ +/* is not accessed. C is an input variable if FACT = 'F'; */ +/* otherwise, C is an output variable. If FACT = 'F' and */ +/* EQUED = 'C' or 'B', each element of C must be positive. */ + +/* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */ +/* On entry, the N-by-NRHS right-hand side matrix B. */ +/* On exit, if EQUED = 'N', B is not modified; if TRANS = 'N' */ +/* and EQUED = 'R' or 'B', B is overwritten by diag(R)*B; if */ +/* TRANS = 'T' or 'C' and EQUED = 'C' or 'B', B is overwritten */ +/* by diag(C)*B. */ + +/* LDB (input) INTEGER */ +/* The leading dimension of the array B. LDB >= max(1,N). */ + +/* X (output) DOUBLE PRECISION array, dimension (LDX,NRHS) */ +/* If INFO = 0, the N-by-NRHS solution matrix X to the original +*/ +/* system of equations. Note that A and B are modified on exit +*/ +/* if EQUED .ne. 'N', and the solution to the equilibrated */ +/* system is inv(diag(C))*X if TRANS = 'N' and EQUED = 'C' or */ +/* 'B', or inv(diag(R))*X if TRANS = 'T' or 'C' and EQUED = 'R' +*/ +/* or 'B'. */ + +/* LDX (input) INTEGER */ +/* The leading dimension of the array X. LDX >= max(1,N). */ + +/* RCOND (output) DOUBLE PRECISION */ +/* The estimate of the reciprocal condition number of the matrix +*/ +/* A after equilibration (if done). If RCOND is less than the */ +/* machine precision (in particular, if RCOND = 0), the matrix */ +/* is singular to working precision. This condition is */ +/* indicated by a return code of INFO > 0, and the solution and +*/ +/* error bounds are not computed. */ + +/* FERR (output) DOUBLE PRECISION array, dimension (NRHS) */ +/* The estimated forward error bounds for each solution vector */ +/* X(j) (the j-th column of the solution matrix X). */ +/* If XTRUE is the true solution, FERR(j) bounds the magnitude */ +/* of the largest entry in (X(j) - XTRUE) divided by */ +/* the magnitude of the largest entry in X(j). The quality of */ +/* the error bound depends on the quality of the estimate of */ +/* norm(inv(A)) computed in the code; if the estimate of */ +/* norm(inv(A)) is accurate, the error bound is guaranteed. */ + +/* BERR (output) DOUBLE PRECISION array, dimension (NRHS) */ +/* The componentwise relative backward error of each solution */ +/* vector X(j) (i.e., the smallest relative change in */ +/* any entry of A or B that makes X(j) an exact solution). */ + +/* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */ + +/* IWORK (workspace) INTEGER array, dimension (N) */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -i, the i-th argument had an illegal value */ +/* > 0: if INFO = i, and i is */ +/* <= N: U(i,i) is exactly zero. The factorization has */ +/* been completed, but the factor U is exactly */ +/* singular, so the solution and error bounds */ +/* could not be computed. */ +/* = N+1: RCOND is less than machine precision. The */ +/* factorization has been completed, but the */ +/* matrix is singular to working precision, and */ +/* the solution and error bounds have not been */ +/* computed. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + af_dim1 = *ldaf; + af_offset = af_dim1 + 1; + af -= af_offset; + --ipiv; + --r; + --c; + b_dim1 = *ldb; + b_offset = b_dim1 + 1; + b -= b_offset; + x_dim1 = *ldx; + x_offset = x_dim1 + 1; + x -= x_offset; + --ferr; + --berr; + --work; + --iwork; + + /* Function Body */ + *info = 0; + nofact = lsame_(fact, "N", 1L, 1L); + equil = lsame_(fact, "E", 1L, 1L); + notran = lsame_(trans, "N", 1L, 1L); + if (nofact || equil) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE_; + colequ = FALSE_; + } else { + rowequ = lsame_(equed, "R", 1L, 1L) || lsame_(equed, "B", 1L, 1L); + colequ = lsame_(equed, "C", 1L, 1L) || lsame_(equed, "B", 1L, 1L); + smlnum = dlamch_("Safe minimum", 12L); + bignum = 1. / smlnum; + } + +/* Test the input parameters. */ + + if (! nofact && ! equil && ! lsame_(fact, "F", 1L, 1L)) { + *info = -1; + } else if (! notran && ! lsame_(trans, "T", 1L, 1L) && ! lsame_(trans, + "C", 1L, 1L)) { + *info = -2; + } else if (*n < 0) { + *info = -3; + } else if (*nrhs < 0) { + *info = -4; + } else if (*lda < max(1,*n)) { + *info = -6; + } else if (*ldaf < max(1,*n)) { + *info = -8; + } else if (lsame_(fact, "F", 1L, 1L) && ! (rowequ || colequ || lsame_( + equed, "N", 1L, 1L))) { + *info = -10; + } else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { +/* Computing MIN */ + d__1 = rcmin, d__2 = r[j]; + rcmin = min(d__1,d__2); +/* Computing MAX */ + d__1 = rcmax, d__2 = r[j]; + rcmax = max(d__1,d__2); +/* L10: */ + } + if (rcmin <= 0.) { + *info = -11; + } else if (*n > 0) { + rowcnd = max(rcmin,smlnum) / min(rcmax,bignum); + } else { + rowcnd = 1.; + } + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { +/* Computing MIN */ + d__1 = rcmin, d__2 = c[j]; + rcmin = min(d__1,d__2); +/* Computing MAX */ + d__1 = rcmax, d__2 = c[j]; + rcmax = max(d__1,d__2); +/* L20: */ + } + if (rcmin <= 0.) { + *info = -12; + } else if (*n > 0) { + colcnd = max(rcmin,smlnum) / min(rcmax,bignum); + } else { + colcnd = 1.; + } + } + if (*info == 0) { + if (*ldb < max(1,*n)) { + *info = -14; + } else if (*ldx < max(1,*n)) { + *info = -16; + } + } + } + + if (*info != 0) { + i__1 = -(*info); + xerbla_("DGESVX", &i__1, 6L); + return 0; + } + + if (equil) { + +/* Compute row and column scalings to equilibrate the matrix A. + */ + + dgeequ_(n, n, &a[a_offset], lda, &r[1], &c[1], &rowcnd, &colcnd, & + amax, &infequ); + if (infequ == 0) { + +/* Equilibrate the matrix. */ + + dlaqge_(n, n, &a[a_offset], lda, &r[1], &c[1], &rowcnd, &colcnd, & + amax, equed, 1L); + rowequ = lsame_(equed, "R", 1L, 1L) || lsame_(equed, "B", 1L, 1L); + colequ = lsame_(equed, "C", 1L, 1L) || lsame_(equed, "B", 1L, 1L); + } + } + +/* Scale the right-hand side. */ + + if (notran) { + if (rowequ) { + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = r[i] * b[i + j * b_dim1]; +/* L30: */ + } +/* L40: */ + } + } + } else if (colequ) { + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = c[i] * b[i + j * b_dim1]; +/* L50: */ + } +/* L60: */ + } + } + + if (nofact || equil) { + +/* Compute the LU factorization of A. */ + + dlacpy_("Full", n, n, &a[a_offset], lda, &af[af_offset], ldaf, 4L); + dgetrf_(n, n, &af[af_offset], ldaf, &ipiv[1], info); + +/* Return if INFO is non-zero. */ + + if (*info != 0) { + if (*info > 0) { + *rcond = 0.; + } + return 0; + } + } + +/* Compute the norm of the matrix A. */ + + if (notran) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = dlange_(norm, n, n, &a[a_offset], lda, &work[1], 1L); + +/* Compute the reciprocal of the condition number of A. */ + + dgecon_(norm, n, &af[af_offset], ldaf, &anorm, rcond, &work[1], &iwork[1], + info, 1L); + +/* Return if the matrix is singular to working precision. */ + + if (*rcond < dlamch_("Epsilon", 7L)) { + *info = *n + 1; + return 0; + } + +/* Compute the solution matrix X. */ + + dlacpy_("Full", n, nrhs, &b[b_offset], ldb, &x[x_offset], ldx, 4L); + dgetrs_(trans, n, nrhs, &af[af_offset], ldaf, &ipiv[1], &x[x_offset], ldx, + info, 1L); + +/* Use iterative refinement to improve the computed solution and */ +/* compute error bounds and backward error estimates for it. */ + + dgerfs_(trans, n, nrhs, &a[a_offset], lda, &af[af_offset], ldaf, &ipiv[1], + &b[b_offset], ldb, &x[x_offset], ldx, &ferr[1], &berr[1], &work[ + 1], &iwork[1], info, 1L); + +/* Transform the solution matrix X to a solution of the original */ +/* system. */ + + if (notran) { + if (colequ) { + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + x[i + j * x_dim1] = c[i] * x[i + j * x_dim1]; +/* L70: */ + } +/* L80: */ + } + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + ferr[j] /= colcnd; +/* L90: */ + } + } + } else if (rowequ) { + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + i__2 = *n; + for (i = 1; i <= i__2; ++i) { + x[i + j * x_dim1] = r[i] * x[i + j * x_dim1]; +/* L100: */ + } +/* L110: */ + } + i__1 = *nrhs; + for (j = 1; j <= i__1; ++j) { + ferr[j] /= rowcnd; +/* L120: */ + } + } + + return 0; + +/* End of DGESVX */ + +} /* dgesvx_ */ + diff --git a/src/matrix/camlapack/dgetf2.c b/src/matrix/camlapack/dgetf2.c new file mode 100644 index 0000000..fa0e441 --- /dev/null +++ b/src/matrix/camlapack/dgetf2.c @@ -0,0 +1,174 @@ +/* DGETF2.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; +static doublereal c_b6 = -1.; + +/* Subroutine */ int dgetf2_(m, n, a, lda, ipiv, info) +integer *m, *n; +doublereal *a; +integer *lda, *ipiv, *info; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2, i__3; + doublereal d__1; + + /* Local variables */ + extern /* Subroutine */ int dger_(); + static integer j; + extern /* Subroutine */ int dscal_(), dswap_(); + static integer jp; + extern integer idamax_(); + extern /* Subroutine */ int xerbla_(); + + +/* -- LAPACK routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* June 30, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGETF2 computes an LU factorization of a general m-by-n matrix A */ +/* using partial pivoting with row interchanges. */ + +/* The factorization has the form */ +/* A = P * L * U */ +/* where P is a permutation matrix, L is lower triangular with unit */ +/* diagonal elements (lower trapezoidal if m > n), and U is upper */ +/* triangular (upper trapezoidal if m < n). */ + +/* This is the right-looking Level 2 BLAS version of the algorithm. */ + +/* Arguments */ +/* ========= */ + +/* M (input) INTEGER */ +/* The number of rows of the matrix A. M >= 0. */ + +/* N (input) INTEGER */ +/* The number of columns of the matrix A. N >= 0. */ + +/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */ +/* On entry, the m by n matrix to be factored. */ +/* On exit, the factors L and U from the factorization */ +/* A = P*L*U; the unit diagonal elements of L are not stored. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,M). */ + +/* IPIV (output) INTEGER array, dimension (min(M,N)) */ +/* The pivot indices; for 1 <= i <= min(M,N), row i of the */ +/* matrix was interchanged with row IPIV(i). */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -k, the k-th argument had an illegal value */ +/* > 0: if INFO = k, U(k,k) is exactly zero. The factorization */ +/* has been completed, but the factor U is exactly */ +/* singular, and division by zero will occur if it is used +*/ +/* to solve a system of equations. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --ipiv; + + /* Function Body */ + *info = 0; + if (*m < 0) { + *info = -1; + } else if (*n < 0) { + *info = -2; + } else if (*lda < max(1,*m)) { + *info = -4; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DGETF2", &i__1, 6L); + return 0; + } + +/* Quick return if possible */ + + if (*m == 0 || *n == 0) { + return 0; + } + + i__1 = min(*m,*n); + for (j = 1; j <= i__1; ++j) { + +/* Find pivot and test for singularity. */ + + i__2 = *m - j + 1; + jp = j - 1 + idamax_(&i__2, &a[j + j * a_dim1], &c__1); + ipiv[j] = jp; + if (a[jp + j * a_dim1] != 0.) { + +/* Apply the interchange to columns 1:N. */ + + if (jp != j) { + dswap_(n, &a[j + a_dim1], lda, &a[jp + a_dim1], lda); + } + +/* Compute elements J+1:M of J-th column. */ + + if (j < *m) { + i__2 = *m - j; + d__1 = 1. / a[j + j * a_dim1]; + dscal_(&i__2, &d__1, &a[j + 1 + j * a_dim1], &c__1); + } + + } else if (*info == 0) { + + *info = j; + } + + if (j < min(*m,*n)) { + +/* Update trailing submatrix. */ + + i__2 = *m - j; + i__3 = *n - j; + dger_(&i__2, &i__3, &c_b6, &a[j + 1 + j * a_dim1], &c__1, &a[j + ( + j + 1) * a_dim1], lda, &a[j + 1 + (j + 1) * a_dim1], lda); + } +/* L10: */ + } + return 0; + +/* End of DGETF2 */ + +} /* dgetf2_ */ + diff --git a/src/matrix/camlapack/dgetrf.c b/src/matrix/camlapack/dgetrf.c new file mode 100644 index 0000000..b9a1e9a --- /dev/null +++ b/src/matrix/camlapack/dgetrf.c @@ -0,0 +1,213 @@ +/* DGETRF.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; +static integer c_n1 = -1; +static doublereal c_b16 = 1.; +static doublereal c_b19 = -1.; + +/* Subroutine */ int dgetrf_(m, n, a, lda, ipiv, info) +integer *m, *n; +doublereal *a; +integer *lda, *ipiv, *info; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; + + /* Local variables */ + static integer i, j; + extern /* Subroutine */ int dgemm_(); + static integer iinfo; + extern /* Subroutine */ int dtrsm_(), dgetf2_(); + static integer jb, nb; + extern /* Subroutine */ int xerbla_(); + extern integer ilaenv_(); + extern /* Subroutine */ int dlaswp_(); + + +/* -- LAPACK routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* March 31, 1993 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGETRF computes an LU factorization of a general M-by-N matrix A */ +/* using partial pivoting with row interchanges. */ + +/* The factorization has the form */ +/* A = P * L * U */ +/* where P is a permutation matrix, L is lower triangular with unit */ +/* diagonal elements (lower trapezoidal if m > n), and U is upper */ +/* triangular (upper trapezoidal if m < n). */ + +/* This is the right-looking Level 3 BLAS version of the algorithm. */ + +/* Arguments */ +/* ========= */ + +/* M (input) INTEGER */ +/* The number of rows of the matrix A. M >= 0. */ + +/* N (input) INTEGER */ +/* The number of columns of the matrix A. N >= 0. */ + +/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */ +/* On entry, the M-by-N matrix to be factored. */ +/* On exit, the factors L and U from the factorization */ +/* A = P*L*U; the unit diagonal elements of L are not stored. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,M). */ + +/* IPIV (output) INTEGER array, dimension (min(M,N)) */ +/* The pivot indices; for 1 <= i <= min(M,N), row i of the */ +/* matrix was interchanged with row IPIV(i). */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -i, the i-th argument had an illegal value */ +/* > 0: if INFO = i, U(i,i) is exactly zero. The factorization +*/ +/* has been completed, but the factor U is exactly */ +/* singular, and division by zero will occur if it is used +*/ +/* to solve a system of equations. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --ipiv; + + /* Function Body */ + *info = 0; + if (*m < 0) { + *info = -1; + } else if (*n < 0) { + *info = -2; + } else if (*lda < max(1,*m)) { + *info = -4; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DGETRF", &i__1, 6L); + return 0; + } + +/* Quick return if possible */ + + if (*m == 0 || *n == 0) { + return 0; + } + +/* Determine the block size for this environment. */ + + nb = ilaenv_(&c__1, "DGETRF", " ", m, n, &c_n1, &c_n1, 6L, 1L); + if (nb <= 1 || nb >= min(*m,*n)) { + +/* Use unblocked code. */ + + dgetf2_(m, n, &a[a_offset], lda, &ipiv[1], info); + } else { + +/* Use blocked code. */ + + i__1 = min(*m,*n); + i__2 = nb; + for (j = 1; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { +/* Computing MIN */ + i__3 = min(*m,*n) - j + 1; + jb = min(i__3,nb); + +/* Factor diagonal and subdiagonal blocks and test for e +xact */ +/* singularity. */ + + i__3 = *m - j + 1; + dgetf2_(&i__3, &jb, &a[j + j * a_dim1], lda, &ipiv[j], &iinfo); + +/* Adjust INFO and the pivot indices. */ + + if (*info == 0 && iinfo > 0) { + *info = iinfo + j - 1; + } +/* Computing MIN */ + i__4 = *m, i__5 = j + jb - 1; + i__3 = min(i__4,i__5); + for (i = j; i <= i__3; ++i) { + ipiv[i] = j - 1 + ipiv[i]; +/* L10: */ + } + +/* Apply interchanges to columns 1:J-1. */ + + i__3 = j - 1; + i__4 = j + jb - 1; + dlaswp_(&i__3, &a[a_offset], lda, &j, &i__4, &ipiv[1], &c__1); + + if (j + jb <= *n) { + +/* Apply interchanges to columns J+JB:N. */ + + i__3 = *n - j - jb + 1; + i__4 = j + jb - 1; + dlaswp_(&i__3, &a[(j + jb) * a_dim1 + 1], lda, &j, &i__4, & + ipiv[1], &c__1); + +/* Compute block row of U. */ + + i__3 = *n - j - jb + 1; + dtrsm_("Left", "Lower", "No transpose", "Unit", &jb, &i__3, & + c_b16, &a[j + j * a_dim1], lda, &a[j + (j + jb) * + a_dim1], lda, 4L, 5L, 12L, 4L); + if (j + jb <= *m) { + +/* Update trailing submatrix. */ + + i__3 = *m - j - jb + 1; + i__4 = *n - j - jb + 1; + dgemm_("No transpose", "No transpose", &i__3, &i__4, &jb, + &c_b19, &a[j + jb + j * a_dim1], lda, &a[j + (j + + jb) * a_dim1], lda, &c_b16, &a[j + jb + (j + jb) * + a_dim1], lda, 12L, 12L); + } + } +/* L20: */ + } + } + return 0; + +/* End of DGETRF */ + +} /* dgetrf_ */ + diff --git a/src/matrix/camlapack/dgetrs.c b/src/matrix/camlapack/dgetrs.c new file mode 100644 index 0000000..5e8d1f3 --- /dev/null +++ b/src/matrix/camlapack/dgetrs.c @@ -0,0 +1,183 @@ +/* DGETRS.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; +static doublereal c_b12 = 1.; +static integer c_n1 = -1; + +/* Subroutine */ int dgetrs_(trans, n, nrhs, a, lda, ipiv, b, ldb, info, + trans_len) +char *trans; +integer *n, *nrhs; +doublereal *a; +integer *lda, *ipiv; +doublereal *b; +integer *ldb, *info; +ftnlen trans_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, b_dim1, b_offset, i__1; + + /* Local variables */ + extern logical lsame_(); + extern /* Subroutine */ int dtrsm_(), xerbla_(), dlaswp_(); + static logical notran; + + +/* -- LAPACK routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* March 31, 1993 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DGETRS solves a system of linear equations */ +/* A * X = B or A' * X = B */ +/* with a general N-by-N matrix A using the LU factorization computed */ +/* by DGETRF. */ + +/* Arguments */ +/* ========= */ + +/* TRANS (input) CHARACTER*1 */ +/* Specifies the form of the system of equations: */ +/* = 'N': A * X = B (No transpose) */ +/* = 'T': A'* X = B (Transpose) */ +/* = 'C': A'* X = B (Conjugate transpose = Transpose) */ + +/* N (input) INTEGER */ +/* The order of the matrix A. N >= 0. */ + +/* NRHS (input) INTEGER */ +/* The number of right hand sides, i.e., the number of columns */ +/* of the matrix B. NRHS >= 0. */ + +/* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ +/* The factors L and U from the factorization A = P*L*U */ +/* as computed by DGETRF. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,N). */ + +/* IPIV (input) INTEGER array, dimension (N) */ +/* The pivot indices from DGETRF; for 1<=i<=N, row i of the */ +/* matrix was interchanged with row IPIV(i). */ + +/* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */ +/* On entry, the right hand side matrix B. */ +/* On exit, the solution matrix X. */ + +/* LDB (input) INTEGER */ +/* The leading dimension of the array B. LDB >= max(1,N). */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -i, the i-th argument had an illegal value */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --ipiv; + b_dim1 = *ldb; + b_offset = b_dim1 + 1; + b -= b_offset; + + /* Function Body */ + *info = 0; + notran = lsame_(trans, "N", 1L, 1L); + if (! notran && ! lsame_(trans, "T", 1L, 1L) && ! lsame_(trans, "C", 1L, + 1L)) { + *info = -1; + } else if (*n < 0) { + *info = -2; + } else if (*nrhs < 0) { + *info = -3; + } else if (*lda < max(1,*n)) { + *info = -5; + } else if (*ldb < max(1,*n)) { + *info = -8; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DGETRS", &i__1, 6L); + return 0; + } + +/* Quick return if possible */ + + if (*n == 0 || *nrhs == 0) { + return 0; + } + + if (notran) { + +/* Solve A * X = B. */ + +/* Apply row interchanges to the right hand sides. */ + + dlaswp_(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c__1); + +/* Solve L*X = B, overwriting B with X. */ + + dtrsm_("Left", "Lower", "No transpose", "Unit", n, nrhs, &c_b12, &a[ + a_offset], lda, &b[b_offset], ldb, 4L, 5L, 12L, 4L); + +/* Solve U*X = B, overwriting B with X. */ + + dtrsm_("Left", "Upper", "No transpose", "Non-unit", n, nrhs, &c_b12, & + a[a_offset], lda, &b[b_offset], ldb, 4L, 5L, 12L, 8L); + } else { + +/* Solve A' * X = B. */ + +/* Solve U'*X = B, overwriting B with X. */ + + dtrsm_("Left", "Upper", "Transpose", "Non-unit", n, nrhs, &c_b12, &a[ + a_offset], lda, &b[b_offset], ldb, 4L, 5L, 9L, 8L); + +/* Solve L'*X = B, overwriting B with X. */ + + dtrsm_("Left", "Lower", "Transpose", "Unit", n, nrhs, &c_b12, &a[ + a_offset], lda, &b[b_offset], ldb, 4L, 5L, 9L, 4L); + +/* Apply row interchanges to the solution vectors. */ + + dlaswp_(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c_n1); + } + + return 0; + +/* End of DGETRS */ + +} /* dgetrs_ */ + diff --git a/src/matrix/camlapack/dlabad.c b/src/matrix/camlapack/dlabad.c new file mode 100644 index 0000000..d4e463b --- /dev/null +++ b/src/matrix/camlapack/dlabad.c @@ -0,0 +1,72 @@ +/* DLABAD.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Subroutine */ int dlabad_(small, large) +doublereal *small, *large; +{ + /* Builtin functions */ + double d_lg10(), sqrt(); + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLABAD takes as input the values computed by SLAMCH for underflow and +*/ +/* overflow, and returns the square root of each of these values if the +*/ +/* log of LARGE is sufficiently large. This subroutine is intended to */ +/* identify machines with a large exponent range, such as the Crays, and +*/ +/* redefine the underflow and overflow limits to be the square roots of +*/ +/* the values computed by DLAMCH. This subroutine is needed because */ +/* DLAMCH does not compensate for poor arithmetic in the upper half of */ +/* the exponent range, as is found on a Cray. */ + +/* Arguments */ +/* ========= */ + +/* SMALL (input/output) DOUBLE PRECISION */ +/* On entry, the underflow threshold as computed by DLAMCH. */ +/* On exit, if LOG10(LARGE) is sufficiently large, the square */ +/* root of SMALL, otherwise unchanged. */ + +/* LARGE (input/output) DOUBLE PRECISION */ +/* On entry, the overflow threshold as computed by DLAMCH. */ +/* On exit, if LOG10(LARGE) is sufficiently large, the square */ +/* root of LARGE, otherwise unchanged. */ + +/* ===================================================================== +*/ + +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* If it looks like we're on a Cray, take the square root of */ +/* SMALL and LARGE to avoid overflow and underflow problems. */ + + if (d_lg10(large) > 2e3) { + *small = sqrt(*small); + *large = sqrt(*large); + } + + return 0; + +/* End of DLABAD */ + +} /* dlabad_ */ + diff --git a/src/matrix/camlapack/dlacon.c b/src/matrix/camlapack/dlacon.c new file mode 100644 index 0000000..273c51c --- /dev/null +++ b/src/matrix/camlapack/dlacon.c @@ -0,0 +1,256 @@ +/* DLACON.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; +static doublereal c_b11 = 1.; + +/* Subroutine */ int dlacon_(n, v, x, isgn, est, kase) +integer *n; +doublereal *v, *x; +integer *isgn; +doublereal *est; +integer *kase; +{ + /* System generated locals */ + integer i__1; + doublereal d__1; + + /* Builtin functions */ + double d_sign(); + integer i_dnnt(); + + /* Local variables */ + static integer iter; + static doublereal temp; + static integer jump, i, j; + extern doublereal dasum_(); + static integer jlast; + extern /* Subroutine */ int dcopy_(); + extern integer idamax_(); + static doublereal altsgn, estold; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* February 29, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLACON estimates the 1-norm of a square, real matrix A. */ +/* Reverse communication is used for evaluating matrix-vector products. +*/ + +/* Arguments */ +/* ========= */ + +/* N (input) INTEGER */ +/* The order of the matrix. N >= 1. */ + +/* V (workspace) DOUBLE PRECISION array, dimension (N) */ +/* On the final return, V = A*W, where EST = norm(V)/norm(W) */ +/* (W is not returned). */ + +/* X (input/output) DOUBLE PRECISION array, dimension (N) */ +/* On an intermediate return, X should be overwritten by */ +/* A * X, if KASE=1, */ +/* A' * X, if KASE=2, */ +/* and DLACON must be re-called with all the other parameters */ +/* unchanged. */ + +/* ISGN (workspace) INTEGER array, dimension (N) */ + +/* EST (output) DOUBLE PRECISION */ +/* An estimate (a lower bound) for norm(A). */ + +/* KASE (input/output) INTEGER */ +/* On the initial call to DLACON, KASE should be 0. */ +/* On an intermediate return, KASE will be 1 or 2, indicating */ +/* whether X should be overwritten by A * X or A' * X. */ +/* On the final return from DLACON, KASE will again be 0. */ + +/* Further Details */ +/* ======= ======= */ + +/* Contributed by Nick Higham, University of Manchester. */ +/* Originally named SONEST, dated March 16, 1988. */ + +/* Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of +*/ +/* a real or complex matrix, with applications to condition estimation", +*/ +/* ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Save statement .. */ +/* .. */ +/* .. Executable Statements .. */ + + /* Parameter adjustments */ + --isgn; + --x; + --v; + + /* Function Body */ + if (*kase == 0) { + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + x[i] = 1. / (doublereal) (*n); +/* L10: */ + } + *kase = 1; + jump = 1; + return 0; + } + + switch ((int)jump) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + +/* ................ ENTRY (JUMP = 1) */ +/* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + +L20: + if (*n == 1) { + v[1] = x[1]; + *est = abs(v[1]); +/* ... QUIT */ + goto L150; + } + *est = dasum_(n, &x[1], &c__1); + + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + x[i] = d_sign(&c_b11, &x[i]); + isgn[i] = i_dnnt(&x[i]); +/* L30: */ + } + *kase = 2; + jump = 2; + return 0; + +/* ................ ENTRY (JUMP = 2) */ +/* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ + +L40: + j = idamax_(n, &x[1], &c__1); + iter = 2; + +/* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ + +L50: + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + x[i] = 0.; +/* L60: */ + } + x[j] = 1.; + *kase = 1; + jump = 3; + return 0; + +/* ................ ENTRY (JUMP = 3) */ +/* X HAS BEEN OVERWRITTEN BY A*X. */ + +L70: + dcopy_(n, &x[1], &c__1, &v[1], &c__1); + estold = *est; + *est = dasum_(n, &v[1], &c__1); + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + d__1 = d_sign(&c_b11, &x[i]); + if (i_dnnt(&d__1) != isgn[i]) { + goto L90; + } +/* L80: */ + } +/* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED. */ + goto L120; + +L90: +/* TEST FOR CYCLING. */ + if (*est <= estold) { + goto L120; + } + + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + x[i] = d_sign(&c_b11, &x[i]); + isgn[i] = i_dnnt(&x[i]); +/* L100: */ + } + *kase = 2; + jump = 4; + return 0; + +/* ................ ENTRY (JUMP = 4) */ +/* X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ + +L110: + jlast = j; + j = idamax_(n, &x[1], &c__1); + if (x[jlast] != (d__1 = x[j], abs(d__1)) && iter < 5) { + ++iter; + goto L50; + } + +/* ITERATION COMPLETE. FINAL STAGE. */ + +L120: + altsgn = 1.; + i__1 = *n; + for (i = 1; i <= i__1; ++i) { + x[i] = altsgn * ((doublereal) (i - 1) / (doublereal) (*n - 1) + 1.); + altsgn = -altsgn; +/* L130: */ + } + *kase = 1; + jump = 5; + return 0; + +/* ................ ENTRY (JUMP = 5) */ +/* X HAS BEEN OVERWRITTEN BY A*X. */ + +L140: + temp = dasum_(n, &x[1], &c__1) / (doublereal) (*n * 3) * 2.; + if (temp > *est) { + dcopy_(n, &x[1], &c__1, &v[1], &c__1); + *est = temp; + } + +L150: + *kase = 0; + return 0; + +/* End of DLACON */ + +} /* dlacon_ */ + diff --git a/src/matrix/camlapack/dlacpy.c b/src/matrix/camlapack/dlacpy.c new file mode 100644 index 0000000..06018e8 --- /dev/null +++ b/src/matrix/camlapack/dlacpy.c @@ -0,0 +1,127 @@ +/* DLACPY.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Subroutine */ int dlacpy_(uplo, m, n, a, lda, b, ldb, uplo_len) +char *uplo; +integer *m, *n; +doublereal *a; +integer *lda; +doublereal *b; +integer *ldb; +ftnlen uplo_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2; + + /* Local variables */ + static integer i, j; + extern logical lsame_(); + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* February 29, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLACPY copies all or part of a two-dimensional matrix A to another */ +/* matrix B. */ + +/* Arguments */ +/* ========= */ + +/* UPLO (input) CHARACTER*1 */ +/* Specifies the part of the matrix A to be copied to B. */ +/* = 'U': Upper triangular part */ +/* = 'L': Lower triangular part */ +/* Otherwise: All of the matrix A */ + +/* M (input) INTEGER */ +/* The number of rows of the matrix A. M >= 0. */ + +/* N (input) INTEGER */ +/* The number of columns of the matrix A. N >= 0. */ + +/* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ +/* The m by n matrix A. If UPLO = 'U', only the upper triangle +*/ +/* or trapezoid is accessed; if UPLO = 'L', only the lower */ +/* triangle or trapezoid is accessed. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(1,M). */ + +/* B (output) DOUBLE PRECISION array, dimension (LDB,N) */ +/* On exit, B = A in the locations specified by UPLO. */ + +/* LDB (input) INTEGER */ +/* The leading dimension of the array B. LDB >= max(1,M). */ + +/* ===================================================================== +*/ + +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + b_dim1 = *ldb; + b_offset = b_dim1 + 1; + b -= b_offset; + + /* Function Body */ + if (lsame_(uplo, "U", 1L, 1L)) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = min(j,*m); + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = a[i + j * a_dim1]; +/* L10: */ + } +/* L20: */ + } + } else if (lsame_(uplo, "L", 1L, 1L)) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = j; i <= i__2; ++i) { + b[i + j * b_dim1] = a[i + j * a_dim1]; +/* L30: */ + } +/* L40: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = a[i + j * a_dim1]; +/* L50: */ + } +/* L60: */ + } + } + return 0; + +/* End of DLACPY */ + +} /* dlacpy_ */ + diff --git a/src/matrix/camlapack/dlamch.c b/src/matrix/camlapack/dlamch.c new file mode 100644 index 0000000..1ff4606 --- /dev/null +++ b/src/matrix/camlapack/dlamch.c @@ -0,0 +1,1046 @@ +/* DLAMCH.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static doublereal c_b31 = 0.; + +doublereal dlamch_(cmach, cmach_len) +char *cmach; +ftnlen cmach_len; +{ + /* Initialized data */ + + static logical first = TRUE_; + + /* System generated locals */ + integer i__1; + doublereal ret_val; + + /* Builtin functions */ + double pow_di(); + + /* Local variables */ + static doublereal base; + static integer beta; + static doublereal emin, prec, emax; + static integer imin, imax; + static logical lrnd; + static doublereal rmin, rmax, t, rmach; + extern logical lsame_(); + static doublereal small, sfmin; + extern /* Subroutine */ int dlamc2_(); + static integer it; + static doublereal rnd, eps; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLAMCH determines double precision machine parameters. */ + +/* Arguments */ +/* ========= */ + +/* CMACH (input) CHARACTER*1 */ +/* Specifies the value to be returned by DLAMCH: */ +/* = 'E' or 'e', DLAMCH := eps */ +/* = 'S' or 's , DLAMCH := sfmin */ +/* = 'B' or 'b', DLAMCH := base */ +/* = 'P' or 'p', DLAMCH := eps*base */ +/* = 'N' or 'n', DLAMCH := t */ +/* = 'R' or 'r', DLAMCH := rnd */ +/* = 'M' or 'm', DLAMCH := emin */ +/* = 'U' or 'u', DLAMCH := rmin */ +/* = 'L' or 'l', DLAMCH := emax */ +/* = 'O' or 'o', DLAMCH := rmax */ + +/* where */ + +/* eps = relative machine precision */ +/* sfmin = safe minimum, such that 1/sfmin does not overflow */ +/* base = base of the machine */ +/* prec = eps*base */ +/* t = number of (base) digits in the mantissa */ +/* rnd = 1.0 when rounding occurs in addition, 0.0 otherwise */ +/* emin = minimum exponent before (gradual) underflow */ +/* rmin = underflow threshold - base**(emin-1) */ +/* emax = largest exponent before overflow */ +/* rmax = overflow threshold - (base**emax)*(1-eps) */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Save statement .. */ +/* .. */ +/* .. Data statements .. */ +/* .. */ +/* .. Executable Statements .. */ + + if (first) { + first = FALSE_; + dlamc2_(&beta, &it, &lrnd, &eps, &imin, &rmin, &imax, &rmax); + base = (doublereal) beta; + t = (doublereal) it; + if (lrnd) { + rnd = 1.; + i__1 = 1 - it; + eps = pow_di(&base, &i__1) / 2; + } else { + rnd = 0.; + i__1 = 1 - it; + eps = pow_di(&base, &i__1); + } + prec = eps * base; + emin = (doublereal) imin; + emax = (doublereal) imax; + sfmin = rmin; + small = 1. / rmax; + if (small >= sfmin) { + +/* Use SMALL plus a bit, to avoid the possibility of rou +nding */ +/* causing overflow when computing 1/sfmin. */ + + sfmin = small * (eps + 1.); + } + } + + if (lsame_(cmach, "E", 1L, 1L)) { + rmach = eps; + } else if (lsame_(cmach, "S", 1L, 1L)) { + rmach = sfmin; + } else if (lsame_(cmach, "B", 1L, 1L)) { + rmach = base; + } else if (lsame_(cmach, "P", 1L, 1L)) { + rmach = prec; + } else if (lsame_(cmach, "N", 1L, 1L)) { + rmach = t; + } else if (lsame_(cmach, "R", 1L, 1L)) { + rmach = rnd; + } else if (lsame_(cmach, "M", 1L, 1L)) { + rmach = emin; + } else if (lsame_(cmach, "U", 1L, 1L)) { + rmach = rmin; + } else if (lsame_(cmach, "L", 1L, 1L)) { + rmach = emax; + } else if (lsame_(cmach, "O", 1L, 1L)) { + rmach = rmax; + } + + ret_val = rmach; + return ret_val; + +/* End of DLAMCH */ + +} /* dlamch_ */ + + +/* *********************************************************************** */ + +/* Subroutine */ int dlamc1_(beta, t, rnd, ieee1) +integer *beta, *t; +logical *rnd, *ieee1; +{ + /* Initialized data */ + + static logical first = TRUE_; + + /* System generated locals */ + doublereal d__1, d__2; + + /* Local variables */ + static logical lrnd; + static doublereal a, b, c, f; + static integer lbeta; + static doublereal savec; + extern doublereal dlamc3_(); + static logical lieee1; + static doublereal t1, t2; + static integer lt; + static doublereal one, qtr; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLAMC1 determines the machine parameters given by BETA, T, RND, and */ +/* IEEE1. */ + +/* Arguments */ +/* ========= */ + +/* BETA (output) INTEGER */ +/* The base of the machine. */ + +/* T (output) INTEGER */ +/* The number of ( BETA ) digits in the mantissa. */ + +/* RND (output) LOGICAL */ +/* Specifies whether proper rounding ( RND = .TRUE. ) or */ +/* chopping ( RND = .FALSE. ) occurs in addition. This may not +*/ +/* be a reliable guide to the way in which the machine performs +*/ +/* its arithmetic. */ + +/* IEEE1 (output) LOGICAL */ +/* Specifies whether rounding appears to be done in the IEEE */ +/* 'round to nearest' style. */ + +/* Further Details */ +/* =============== */ + +/* The routine is based on the routine ENVRON by Malcolm and */ +/* incorporates suggestions by Gentleman and Marovich. See */ + +/* Malcolm M. A. (1972) Algorithms to reveal properties of */ +/* floating-point arithmetic. Comms. of the ACM, 15, 949-951. */ + +/* Gentleman W. M. and Marovich S. B. (1974) More on algorithms */ +/* that reveal properties of floating point arithmetic units. */ +/* Comms. of the ACM, 17, 276-277. */ + +/* ===================================================================== +*/ + +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Save statement .. */ +/* .. */ +/* .. Data statements .. */ +/* .. */ +/* .. Executable Statements .. */ + + if (first) { + first = FALSE_; + one = 1.; + +/* LBETA, LIEEE1, LT and LRND are the local values of BE +TA, */ +/* IEEE1, T and RND. */ + +/* Throughout this routine we use the function DLAMC3 to ens +ure */ +/* that relevant values are stored and not held in registers, + or */ +/* are not affected by optimizers. */ + +/* Compute a = 2.0**m with the smallest positive integer m s +uch */ +/* that */ + +/* fl( a + 1.0 ) = a. */ + + a = 1.; + c = 1.; + +/* + WHILE( C.EQ.ONE )LOOP */ +L10: + if (c == one) { + a *= 2; + c = dlamc3_(&a, &one); + d__1 = -a; + c = dlamc3_(&c, &d__1); + goto L10; + } +/* + END WHILE */ + +/* Now compute b = 2.0**m with the smallest positive integer +m */ +/* such that */ + +/* fl( a + b ) .gt. a. */ + + b = 1.; + c = dlamc3_(&a, &b); + +/* + WHILE( C.EQ.A )LOOP */ +L20: + if (c == a) { + b *= 2; + c = dlamc3_(&a, &b); + goto L20; + } +/* + END WHILE */ + +/* Now compute the base. a and c are neighbouring floating po +int */ +/* numbers in the interval ( beta**t, beta**( t + 1 ) ) and + so */ +/* their difference is beta. Adding 0.25 to c is to ensure that + it */ +/* is truncated to beta and not ( beta - 1 ). */ + + qtr = one / 4; + savec = c; + d__1 = -a; + c = dlamc3_(&c, &d__1); + lbeta = (integer) (c + qtr); + +/* Now determine whether rounding or chopping occurs, by addin +g a */ +/* bit less than beta/2 and a bit more than beta/2 to + a. */ + + b = (doublereal) lbeta; + d__1 = b / 2; + d__2 = -b / 100; + f = dlamc3_(&d__1, &d__2); + c = dlamc3_(&f, &a); + if (c == a) { + lrnd = TRUE_; + } else { + lrnd = FALSE_; + } + d__1 = b / 2; + d__2 = b / 100; + f = dlamc3_(&d__1, &d__2); + c = dlamc3_(&f, &a); + if (lrnd && c == a) { + lrnd = FALSE_; + } + +/* Try and decide whether rounding is done in the IEEE 'round + to */ +/* nearest' style. B/2 is half a unit in the last place of the +two */ +/* numbers A and SAVEC. Furthermore, A is even, i.e. has last +bit */ +/* zero, and SAVEC is odd. Thus adding B/2 to A should not cha +nge */ +/* A, but adding B/2 to SAVEC should change SAVEC. */ + + d__1 = b / 2; + t1 = dlamc3_(&d__1, &a); + d__1 = b / 2; + t2 = dlamc3_(&d__1, &savec); + lieee1 = t1 == a && t2 > savec && lrnd; + +/* Now find the mantissa, t. It should be the integer part + of */ +/* log to the base beta of a, however it is safer to determine + t */ +/* by powering. So we find t as the smallest positive integer +for */ +/* which */ + +/* fl( beta**t + 1.0 ) = 1.0. */ + + lt = 0; + a = 1.; + c = 1.; + +/* + WHILE( C.EQ.ONE )LOOP */ +L30: + if (c == one) { + ++lt; + a *= lbeta; + c = dlamc3_(&a, &one); + d__1 = -a; + c = dlamc3_(&c, &d__1); + goto L30; + } +/* + END WHILE */ + + } + + *beta = lbeta; + *t = lt; + *rnd = lrnd; + *ieee1 = lieee1; + return 0; + +/* End of DLAMC1 */ + +} /* dlamc1_ */ + + +/* *********************************************************************** */ + +/* Subroutine */ int dlamc2_(beta, t, rnd, eps, emin, rmin, emax, rmax) +integer *beta, *t; +logical *rnd; +doublereal *eps; +integer *emin; +doublereal *rmin; +integer *emax; +doublereal *rmax; +{ + /* Initialized data */ + + static logical first = TRUE_; + static logical iwarn = FALSE_; + + /* System generated locals */ + integer i__1; + doublereal d__1, d__2, d__3, d__4, d__5; + + /* Builtin functions */ + double pow_di(); + + /* Local variables */ + static logical ieee; + static doublereal half; + static logical lrnd; + static doublereal leps, zero, a, b, c; + static integer i, lbeta; + static doublereal rbase; + static integer lemin, lemax, gnmin; + static doublereal small; + static integer gpmin; + static doublereal third, lrmin, lrmax, sixth; + extern /* Subroutine */ int dlamc1_(); + extern doublereal dlamc3_(); + static logical lieee1; + extern /* Subroutine */ int dlamc4_(), dlamc5_(); + static integer lt, ngnmin, ngpmin; + static doublereal one, two; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLAMC2 determines the machine parameters specified in its argument */ +/* list. */ + +/* Arguments */ +/* ========= */ + +/* BETA (output) INTEGER */ +/* The base of the machine. */ + +/* T (output) INTEGER */ +/* The number of ( BETA ) digits in the mantissa. */ + +/* RND (output) LOGICAL */ +/* Specifies whether proper rounding ( RND = .TRUE. ) or */ +/* chopping ( RND = .FALSE. ) occurs in addition. This may not +*/ +/* be a reliable guide to the way in which the machine performs +*/ +/* its arithmetic. */ + +/* EPS (output) DOUBLE PRECISION */ +/* The smallest positive number such that */ + +/* fl( 1.0 - EPS ) .LT. 1.0, */ + +/* where fl denotes the computed value. */ + +/* EMIN (output) INTEGER */ +/* The minimum exponent before (gradual) underflow occurs. */ + +/* RMIN (output) DOUBLE PRECISION */ +/* The smallest normalized number for the machine, given by */ +/* BASE**( EMIN - 1 ), where BASE is the floating point value +*/ +/* of BETA. */ + +/* EMAX (output) INTEGER */ +/* The maximum exponent before overflow occurs. */ + +/* RMAX (output) DOUBLE PRECISION */ +/* The largest positive number for the machine, given by */ +/* BASE**EMAX * ( 1 - EPS ), where BASE is the floating point +*/ +/* value of BETA. */ + +/* Further Details */ +/* =============== */ + +/* The computation of EPS is based on a routine PARANOIA by */ +/* W. Kahan of the University of California at Berkeley. */ + +/* ===================================================================== +*/ + +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Save statement .. */ +/* .. */ +/* .. Data statements .. */ +/* .. */ +/* .. Executable Statements .. */ + + if (first) { + first = FALSE_; + zero = 0.; + one = 1.; + two = 2.; + +/* LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values + of */ +/* BETA, T, RND, EPS, EMIN and RMIN. */ + +/* Throughout this routine we use the function DLAMC3 to ens +ure */ +/* that relevant values are stored and not held in registers, + or */ +/* are not affected by optimizers. */ + +/* DLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1. +*/ + + dlamc1_(&lbeta, <, &lrnd, &lieee1); + +/* Start to find EPS. */ + + b = (doublereal) lbeta; + i__1 = -lt; + a = pow_di(&b, &i__1); + leps = a; + +/* Try some tricks to see whether or not this is the correct E +PS. */ + + b = two / 3; + half = one / 2; + d__1 = -half; + sixth = dlamc3_(&b, &d__1); + third = dlamc3_(&sixth, &sixth); + d__1 = -half; + b = dlamc3_(&third, &d__1); + b = dlamc3_(&b, &sixth); + b = abs(b); + if (b < leps) { + b = leps; + } + + leps = 1.; + +/* + WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP */ +L10: + if (leps > b && b > zero) { + leps = b; + d__1 = half * leps; +/* Computing 5th power */ + d__3 = two, d__4 = d__3, d__3 *= d__3; +/* Computing 2nd power */ + d__5 = leps; + d__2 = d__4 * (d__3 * d__3) * (d__5 * d__5); + c = dlamc3_(&d__1, &d__2); + d__1 = -c; + c = dlamc3_(&half, &d__1); + b = dlamc3_(&half, &c); + d__1 = -b; + c = dlamc3_(&half, &d__1); + b = dlamc3_(&half, &c); + goto L10; + } +/* + END WHILE */ + + if (a < leps) { + leps = a; + } + +/* Computation of EPS complete. */ + +/* Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3 +)). */ +/* Keep dividing A by BETA until (gradual) underflow occurs. T +his */ +/* is detected when we cannot recover the previous A. */ + + rbase = one / lbeta; + small = one; + for (i = 1; i <= 3; ++i) { + d__1 = small * rbase; + small = dlamc3_(&d__1, &zero); +/* L20: */ + } + a = dlamc3_(&one, &small); + dlamc4_(&ngpmin, &one, &lbeta); + d__1 = -one; + dlamc4_(&ngnmin, &d__1, &lbeta); + dlamc4_(&gpmin, &a, &lbeta); + d__1 = -a; + dlamc4_(&gnmin, &d__1, &lbeta); + ieee = FALSE_; + + if (ngpmin == ngnmin && gpmin == gnmin) { + if (ngpmin == gpmin) { + lemin = ngpmin; +/* ( Non twos-complement machines, no gradual under +flow; */ +/* e.g., VAX ) */ + } else if (gpmin - ngpmin == 3) { + lemin = ngpmin - 1 + lt; + ieee = TRUE_; +/* ( Non twos-complement machines, with gradual und +erflow; */ +/* e.g., IEEE standard followers ) */ + } else { + lemin = min(ngpmin,gpmin); +/* ( A guess; no known machine ) */ + iwarn = TRUE_; + } + + } else if (ngpmin == gpmin && ngnmin == gnmin) { + if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1) { + lemin = max(ngpmin,ngnmin); +/* ( Twos-complement machines, no gradual underflow +; */ +/* e.g., CYBER 205 ) */ + } else { + lemin = min(ngpmin,ngnmin); +/* ( A guess; no known machine ) */ + iwarn = TRUE_; + } + + } else if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1 && gpmin == gnmin) + { + if (gpmin - min(ngpmin,ngnmin) == 3) { + lemin = max(ngpmin,ngnmin) - 1 + lt; +/* ( Twos-complement machines with gradual underflo +w; */ +/* no known machine ) */ + } else { + lemin = min(ngpmin,ngnmin); +/* ( A guess; no known machine ) */ + iwarn = TRUE_; + } + + } else { +/* Computing MIN */ + i__1 = min(ngpmin,ngnmin), i__1 = min(i__1,gpmin); + lemin = min(i__1,gnmin); +/* ( A guess; no known machine ) */ + iwarn = TRUE_; + } +/* ** */ +/* Comment out this if block if EMIN is ok */ +/* IF( IWARN ) THEN */ +/* FIRST = .TRUE. */ +/* WRITE( 6, FMT = 9999 )LEMIN */ +/* END IF */ +/* ** */ + +/* Assume IEEE arithmetic if we found denormalised numbers abo +ve, */ +/* or if arithmetic seems to round in the IEEE style, determi +ned */ +/* in routine DLAMC1. A true IEEE machine should have both thi +ngs */ +/* true; however, faulty machines may have one or the other. */ + + ieee = ieee || lieee1; + +/* Compute RMIN by successive division by BETA. We could comp +ute */ +/* RMIN as BASE**( EMIN - 1 ), but some machines underflow dur +ing */ +/* this computation. */ + + lrmin = 1.; + i__1 = 1 - lemin; + for (i = 1; i <= i__1; ++i) { + d__1 = lrmin * rbase; + lrmin = dlamc3_(&d__1, &zero); +/* L30: */ + } + +/* Finally, call DLAMC5 to compute EMAX and RMAX. */ + + dlamc5_(&lbeta, <, &lemin, &ieee, &lemax, &lrmax); + } + + *beta = lbeta; + *t = lt; + *rnd = lrnd; + *eps = leps; + *emin = lemin; + *rmin = lrmin; + *emax = lemax; + *rmax = lrmax; + + return 0; + +/* L9999: */ + +/* End of DLAMC2 */ + +} /* dlamc2_ */ + + +/* *********************************************************************** */ + +doublereal dlamc3_(a, b) +doublereal *a, *b; +{ + /* System generated locals */ + doublereal ret_val; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLAMC3 is intended to force A and B to be stored prior to doing +*/ +/* the addition of A and B , for use in situations where optimizers +*/ +/* might hold one of these in a register. */ + +/* Arguments */ +/* ========= */ + +/* A, B (input) DOUBLE PRECISION */ +/* The values A and B. */ + +/* ===================================================================== +*/ + +/* .. Executable Statements .. */ + + ret_val = *a + *b; + + return ret_val; + +/* End of DLAMC3 */ + +} /* dlamc3_ */ + + +/* *********************************************************************** */ + +/* Subroutine */ int dlamc4_(emin, start, base) +integer *emin; +doublereal *start; +integer *base; +{ + /* System generated locals */ + integer i__1; + doublereal d__1; + + /* Local variables */ + static doublereal zero, a; + static integer i; + static doublereal rbase, b1, b2, c1, c2, d1, d2; + extern doublereal dlamc3_(); + static doublereal one; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLAMC4 is a service routine for DLAMC2. */ + +/* Arguments */ +/* ========= */ + +/* EMIN (output) EMIN */ +/* The minimum exponent before (gradual) underflow, computed by +*/ +/* setting A = START and dividing by BASE until the previous A */ +/* can not be recovered. */ + +/* START (input) DOUBLE PRECISION */ +/* The starting point for determining EMIN. */ + +/* BASE (input) INTEGER */ +/* The base of the machine. */ + +/* ===================================================================== +*/ + +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + a = *start; + one = 1.; + rbase = one / *base; + zero = 0.; + *emin = 1; + d__1 = a * rbase; + b1 = dlamc3_(&d__1, &zero); + c1 = a; + c2 = a; + d1 = a; + d2 = a; +/* + WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. */ +/* $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP */ +L10: + if (c1 == a && c2 == a && d1 == a && d2 == a) { + --(*emin); + a = b1; + d__1 = a / *base; + b1 = dlamc3_(&d__1, &zero); + d__1 = b1 * *base; + c1 = dlamc3_(&d__1, &zero); + d1 = zero; + i__1 = *base; + for (i = 1; i <= i__1; ++i) { + d1 += b1; +/* L20: */ + } + d__1 = a * rbase; + b2 = dlamc3_(&d__1, &zero); + d__1 = b2 / rbase; + c2 = dlamc3_(&d__1, &zero); + d2 = zero; + i__1 = *base; + for (i = 1; i <= i__1; ++i) { + d2 += b2; +/* L30: */ + } + goto L10; + } +/* + END WHILE */ + + return 0; + +/* End of DLAMC4 */ + +} /* dlamc4_ */ + + +/* *********************************************************************** */ + +/* Subroutine */ int dlamc5_(beta, p, emin, ieee, emax, rmax) +integer *beta, *p, *emin; +logical *ieee; +integer *emax; +doublereal *rmax; +{ + /* System generated locals */ + integer i__1; + doublereal d__1; + + /* Local variables */ + static integer lexp; + static doublereal oldy; + static integer uexp, i; + static doublereal y, z; + static integer nbits; + extern doublereal dlamc3_(); + static doublereal recbas; + static integer exbits, expsum, try__; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLAMC5 attempts to compute RMAX, the largest machine floating-point */ +/* number, without overflow. It assumes that EMAX + abs(EMIN) sum */ +/* approximately to a power of 2. It will fail on machines where this */ +/* assumption does not hold, for example, the Cyber 205 (EMIN = -28625, +*/ +/* EMAX = 28718). It will also fail if the value supplied for EMIN is */ +/* too large (i.e. too close to zero), probably with overflow. */ + +/* Arguments */ +/* ========= */ + +/* BETA (input) INTEGER */ +/* The base of floating-point arithmetic. */ + +/* P (input) INTEGER */ +/* The number of base BETA digits in the mantissa of a */ +/* floating-point value. */ + +/* EMIN (input) INTEGER */ +/* The minimum exponent before (gradual) underflow. */ + +/* IEEE (input) LOGICAL */ +/* A logical flag specifying whether or not the arithmetic */ +/* system is thought to comply with the IEEE standard. */ + +/* EMAX (output) INTEGER */ +/* The largest exponent before overflow */ + +/* RMAX (output) DOUBLE PRECISION */ +/* The largest machine floating-point number. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* First compute LEXP and UEXP, two powers of 2 that bound */ +/* abs(EMIN). We then assume that EMAX + abs(EMIN) will sum */ +/* approximately to the bound that is closest to abs(EMIN). */ +/* (EMAX is the exponent of the required number RMAX). */ + + lexp = 1; + exbits = 1; +L10: + try__ = lexp << 1; + if (try__ <= -(*emin)) { + lexp = try__; + ++exbits; + goto L10; + } + if (lexp == -(*emin)) { + uexp = lexp; + } else { + uexp = try__; + ++exbits; + } + +/* Now -LEXP is less than or equal to EMIN, and -UEXP is greater */ +/* than or equal to EMIN. EXBITS is the number of bits needed to */ +/* store the exponent. */ + + if (uexp + *emin > -lexp - *emin) { + expsum = lexp << 1; + } else { + expsum = uexp << 1; + } + +/* EXPSUM is the exponent range, approximately equal to */ +/* EMAX - EMIN + 1 . */ + + *emax = expsum + *emin - 1; + nbits = exbits + 1 + *p; + +/* NBITS is the total number of bits needed to store a */ +/* floating-point number. */ + + if (nbits % 2 == 1 && *beta == 2) { + +/* Either there are an odd number of bits used to store a */ +/* floating-point number, which is unlikely, or some bits are +*/ +/* not used in the representation of numbers, which is possible +, */ +/* (e.g. Cray machines) or the mantissa has an implicit bit, */ +/* (e.g. IEEE machines, Dec Vax machines), which is perhaps the + */ +/* most likely. We have to assume the last alternative. */ +/* If this is true, then we need to reduce EMAX by one because +*/ +/* there must be some way of representing zero in an implicit-b +it */ +/* system. On machines like Cray, we are reducing EMAX by one +*/ +/* unnecessarily. */ + + --(*emax); + } + + if (*ieee) { + +/* Assume we are on an IEEE machine which reserves one exponent + */ +/* for infinity and NaN. */ + + --(*emax); + } + +/* Now create RMAX, the largest machine number, which should */ +/* be equal to (1.0 - BETA**(-P)) * BETA**EMAX . */ + +/* First compute 1.0 - BETA**(-P), being careful that the */ +/* result is less than 1.0 . */ + + recbas = 1. / *beta; + z = *beta - 1.; + y = 0.; + i__1 = *p; + for (i = 1; i <= i__1; ++i) { + z *= recbas; + if (y < 1.) { + oldy = y; + } + y = dlamc3_(&y, &z); +/* L20: */ + } + if (y >= 1.) { + y = oldy; + } + +/* Now multiply by BETA**EMAX to get RMAX. */ + + i__1 = *emax; + for (i = 1; i <= i__1; ++i) { + d__1 = y * *beta; + y = dlamc3_(&d__1, &c_b31); +/* L30: */ + } + + *rmax = y; + return 0; + +/* End of DLAMC5 */ + +} /* dlamc5_ */ + diff --git a/src/matrix/camlapack/dlange.c b/src/matrix/camlapack/dlange.c new file mode 100644 index 0000000..390f79c --- /dev/null +++ b/src/matrix/camlapack/dlange.c @@ -0,0 +1,204 @@ +/* DLANGE.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; + +doublereal dlange_(norm, m, n, a, lda, work, norm_len) +char *norm; +integer *m, *n; +doublereal *a; +integer *lda; +doublereal *work; +ftnlen norm_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + doublereal ret_val, d__1, d__2, d__3; + + /* Builtin functions */ + double sqrt(); + + /* Local variables */ + static integer i, j; + static doublereal scale; + extern logical lsame_(); + static doublereal value; + extern /* Subroutine */ int dlassq_(); + static doublereal sum; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLANGE returns the value of the one norm, or the Frobenius norm, or +*/ +/* the infinity norm, or the element of largest absolute value of a +*/ +/* real matrix A. */ + +/* Description */ +/* =========== */ + +/* DLANGE returns the value */ + +/* DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm' */ +/* ( */ +/* ( norm1(A), NORM = '1', 'O' or 'o' */ +/* ( */ +/* ( normI(A), NORM = 'I' or 'i' */ +/* ( */ +/* ( normF(A), NORM = 'F', 'f', 'E' or 'e' */ + +/* where norm1 denotes the one norm of a matrix (maximum column sum), +*/ +/* normI denotes the infinity norm of a matrix (maximum row sum) and +*/ +/* normF denotes the Frobenius norm of a matrix (square root of sum of +*/ +/* squares). Note that max(abs(A(i,j))) is not a matrix norm. */ + +/* Arguments */ +/* ========= */ + +/* NORM (input) CHARACTER*1 */ +/* Specifies the value to be returned in DLANGE as described */ +/* above. */ + +/* M (input) INTEGER */ +/* The number of rows of the matrix A. M >= 0. When M = 0, */ +/* DLANGE is set to zero. */ + +/* N (input) INTEGER */ +/* The number of columns of the matrix A. N >= 0. When N = 0, +*/ +/* DLANGE is set to zero. */ + +/* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ +/* The m by n matrix A. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(M,1). */ + +/* WORK (workspace) DOUBLE PRECISION array, dimension (LWORK), */ +/* where LWORK >= M when NORM = 'I'; otherwise, WORK is not */ +/* referenced. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --work; + + /* Function Body */ + if (min(*m,*n) == 0) { + value = 0.; + } else if (lsame_(norm, "M", 1L, 1L)) { + +/* Find max(abs(A(i,j))). */ + + value = 0.; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { +/* Computing MAX */ + d__2 = value, d__3 = (d__1 = a[i + j * a_dim1], abs(d__1)); + value = max(d__2,d__3); +/* L10: */ + } +/* L20: */ + } + } else if (lsame_(norm, "O", 1L, 1L) || *(unsigned char *)norm == '1') { + +/* Find norm1(A). */ + + value = 0.; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + sum = 0.; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + sum += (d__1 = a[i + j * a_dim1], abs(d__1)); +/* L30: */ + } + value = max(value,sum); +/* L40: */ + } + } else if (lsame_(norm, "I", 1L, 1L)) { + +/* Find normI(A). */ + + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + work[i] = 0.; +/* L50: */ + } + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + work[i] += (d__1 = a[i + j * a_dim1], abs(d__1)); +/* L60: */ + } +/* L70: */ + } + value = 0.; + i__1 = *m; + for (i = 1; i <= i__1; ++i) { +/* Computing MAX */ + d__1 = value, d__2 = work[i]; + value = max(d__1,d__2); +/* L80: */ + } + } else if (lsame_(norm, "F", 1L, 1L) || lsame_(norm, "E", 1L, 1L)) { + +/* Find normF(A). */ + + scale = 0.; + sum = 1.; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + dlassq_(m, &a[j * a_dim1 + 1], &c__1, &scale, &sum); +/* L90: */ + } + value = scale * sqrt(sum); + } + + ret_val = value; + return ret_val; + +/* End of DLANGE */ + +} /* dlange_ */ + diff --git a/src/matrix/camlapack/dlaqge.c b/src/matrix/camlapack/dlaqge.c new file mode 100644 index 0000000..6b3f298 --- /dev/null +++ b/src/matrix/camlapack/dlaqge.c @@ -0,0 +1,191 @@ +/* DLAQGE.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Subroutine */ int dlaqge_(m, n, a, lda, r, c, rowcnd, colcnd, amax, equed, + equed_len) +integer *m, *n; +doublereal *a; +integer *lda; +doublereal *r, *c, *rowcnd, *colcnd, *amax; +char *equed; +ftnlen equed_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer i, j; + static doublereal large, small, cj; + extern doublereal dlamch_(); + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* February 29, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLAQGE equilibrates a general M by N matrix A using the row and */ +/* scaling factors in the vectors R and C. */ + +/* Arguments */ +/* ========= */ + +/* M (input) INTEGER */ +/* The number of rows of the matrix A. M >= 0. */ + +/* N (input) INTEGER */ +/* The number of columns of the matrix A. N >= 0. */ + +/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */ +/* On entry, the M by N matrix A. */ +/* On exit, the equilibrated matrix. See EQUED for the form of +*/ +/* the equilibrated matrix. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max(M,1). */ + +/* R (input) DOUBLE PRECISION array, dimension (M) */ +/* The row scale factors for A. */ + +/* C (input) DOUBLE PRECISION array, dimension (N) */ +/* The column scale factors for A. */ + +/* ROWCND (input) DOUBLE PRECISION */ +/* Ratio of the smallest R(i) to the largest R(i). */ + +/* COLCND (input) DOUBLE PRECISION */ +/* Ratio of the smallest C(i) to the largest C(i). */ + +/* AMAX (input) DOUBLE PRECISION */ +/* Absolute value of largest matrix entry. */ + +/* EQUED (output) CHARACTER*1 */ +/* Specifies the form of equilibration that was done. */ +/* = 'N': No equilibration */ +/* = 'R': Row equilibration, i.e., A has been premultiplied by +*/ +/* diag(R). */ +/* = 'C': Column equilibration, i.e., A has been postmultiplied +*/ +/* by diag(C). */ +/* = 'B': Both row and column equilibration, i.e., A has been */ +/* replaced by diag(R) * A * diag(C). */ + +/* Internal Parameters */ +/* =================== */ + +/* THRESH is a threshold value used to decide if row or column scaling */ +/* should be done based on the ratio of the row or column scaling */ +/* factors. If ROWCND < THRESH, row scaling is done, and if */ +/* COLCND < THRESH, column scaling is done. */ + +/* LARGE and SMALL are threshold values used to decide if row scaling */ +/* should be done based on the absolute size of the largest matrix */ +/* element. If AMAX > LARGE or AMAX < SMALL, row scaling is done. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Quick return if possible */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --r; + --c; + + /* Function Body */ + if (*m <= 0 || *n <= 0) { + *(unsigned char *)equed = 'N'; + return 0; + } + +/* Initialize LARGE and SMALL. */ + + small = dlamch_("Safe minimum", 12L) / dlamch_("Precision", 9L); + large = 1. / small; + + if (*rowcnd >= .1 && *amax >= small && *amax <= large) { + +/* No row scaling */ + + if (*colcnd >= .1) { + +/* No column scaling */ + + *(unsigned char *)equed = 'N'; + } else { + +/* Column scaling */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + cj = c[j]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + a[i + j * a_dim1] = cj * a[i + j * a_dim1]; +/* L10: */ + } +/* L20: */ + } + *(unsigned char *)equed = 'C'; + } + } else if (*colcnd >= .1) { + +/* Row scaling, no column scaling */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + a[i + j * a_dim1] = r[i] * a[i + j * a_dim1]; +/* L30: */ + } +/* L40: */ + } + *(unsigned char *)equed = 'R'; + } else { + +/* Row and column scaling */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + cj = c[j]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + a[i + j * a_dim1] = cj * r[i] * a[i + j * a_dim1]; +/* L50: */ + } +/* L60: */ + } + *(unsigned char *)equed = 'B'; + } + + return 0; + +/* End of DLAQGE */ + +} /* dlaqge_ */ + diff --git a/src/matrix/camlapack/dlassq.c b/src/matrix/camlapack/dlassq.c new file mode 100644 index 0000000..9fadceb --- /dev/null +++ b/src/matrix/camlapack/dlassq.c @@ -0,0 +1,116 @@ +/* dlassq.f -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Subroutine */ int dlassq_(n, x, incx, scale, sumsq) +integer *n; +doublereal *x; +integer *incx; +doublereal *scale, *sumsq; +{ + /* System generated locals */ + integer i__1, i__2; + doublereal d__1; + + /* Local variables */ + static doublereal absxi; + static integer ix; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLASSQ returns the values scl and smsq such that */ + +/* ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq, +*/ + +/* where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is */ +/* assumed to be non-negative and scl returns the value */ + +/* scl = max( scale, abs( x( i ) ) ). */ + +/* scale and sumsq must be supplied in SCALE and SUMSQ and */ +/* scl and smsq are overwritten on SCALE and SUMSQ respectively. */ + +/* The routine makes only one pass through the vector x. */ + +/* Arguments */ +/* ========= */ + +/* N (input) INTEGER */ +/* The number of elements to be used from the vector X. */ + +/* X (input) DOUBLE PRECISION */ +/* The vector for which a scaled sum of squares is computed. */ +/* x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n. */ + +/* INCX (input) INTEGER */ +/* The increment between successive values of the vector X. */ +/* INCX > 0. */ + +/* SCALE (input/output) DOUBLE PRECISION */ +/* On entry, the value scale in the equation above. */ +/* On exit, SCALE is overwritten with scl , the scaling factor +*/ +/* for the sum of squares. */ + +/* SUMSQ (input/output) DOUBLE PRECISION */ +/* On entry, the value sumsq in the equation above. */ +/* On exit, SUMSQ is overwritten with smsq , the basic sum of */ +/* squares from which scl has been factored out. */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + /* Parameter adjustments */ + --x; + + /* Function Body */ + if (*n > 0) { + i__1 = (*n - 1) * *incx + 1; + i__2 = *incx; + for (ix = 1; i__2 < 0 ? ix >= i__1 : ix <= i__1; ix += i__2) { + if (x[ix] != 0.) { + absxi = (d__1 = x[ix], abs(d__1)); + if (*scale < absxi) { +/* Computing 2nd power */ + d__1 = *scale / absxi; + *sumsq = *sumsq * (d__1 * d__1) + 1; + *scale = absxi; + } else { +/* Computing 2nd power */ + d__1 = absxi / *scale; + *sumsq += d__1 * d__1; + } + } +/* L10: */ + } + } + return 0; + +/* End of DLASSQ */ + +} /* dlassq_ */ + diff --git a/src/matrix/camlapack/dlaswp.c b/src/matrix/camlapack/dlaswp.c new file mode 100644 index 0000000..67ad04b --- /dev/null +++ b/src/matrix/camlapack/dlaswp.c @@ -0,0 +1,134 @@ +/* DLASWP.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Subroutine */ int dlaswp_(n, a, lda, k1, k2, ipiv, incx) +integer *n; +doublereal *a; +integer *lda, *k1, *k2, *ipiv, *incx; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1; + + /* Local variables */ + static integer i; + extern /* Subroutine */ int dswap_(); + static integer ip, ix; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLASWP performs a series of row interchanges on the matrix A. */ +/* One row interchange is initiated for each of rows K1 through K2 of A. +*/ + +/* Arguments */ +/* ========= */ + +/* N (input) INTEGER */ +/* The number of columns of the matrix A. */ + +/* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */ +/* On entry, the matrix of column dimension N to which the row */ +/* interchanges will be applied. */ +/* On exit, the permuted matrix. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. */ + +/* K1 (input) INTEGER */ +/* The first element of IPIV for which a row interchange will */ +/* be done. */ + +/* K2 (input) INTEGER */ +/* The last element of IPIV for which a row interchange will */ +/* be done. */ + +/* IPIV (input) INTEGER array, dimension (M*abs(INCX)) */ +/* The vector of pivot indices. Only the elements in positions +*/ +/* K1 through K2 of IPIV are accessed. */ +/* IPIV(K) = L implies rows K and L are to be interchanged. */ + +/* INCX (input) INTEGER */ +/* The increment between successive values of IPIV. If IPIV */ +/* is negative, the pivots are applied in reverse order. */ + +/* ===================================================================== +*/ + +/* .. Local Scalars .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Interchange row I with row IPIV(I) for each of rows K1 through K2. +*/ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --ipiv; + + /* Function Body */ + if (*incx == 0) { + return 0; + } + if (*incx > 0) { + ix = *k1; + } else { + ix = (1 - *k2) * *incx + 1; + } + if (*incx == 1) { + i__1 = *k2; + for (i = *k1; i <= i__1; ++i) { + ip = ipiv[i]; + if (ip != i) { + dswap_(n, &a[i + a_dim1], lda, &a[ip + a_dim1], lda); + } +/* L10: */ + } + } else if (*incx > 1) { + i__1 = *k2; + for (i = *k1; i <= i__1; ++i) { + ip = ipiv[ix]; + if (ip != i) { + dswap_(n, &a[i + a_dim1], lda, &a[ip + a_dim1], lda); + } + ix += *incx; +/* L20: */ + } + } else if (*incx < 0) { + i__1 = *k1; + for (i = *k2; i >= i__1; --i) { + ip = ipiv[ix]; + if (ip != i) { + dswap_(n, &a[i + a_dim1], lda, &a[ip + a_dim1], lda); + } + ix += *incx; +/* L30: */ + } + } + + return 0; + +/* End of DLASWP */ + +} /* dlaswp_ */ + diff --git a/src/matrix/camlapack/dlatrs.c b/src/matrix/camlapack/dlatrs.c new file mode 100644 index 0000000..6f39719 --- /dev/null +++ b/src/matrix/camlapack/dlatrs.c @@ -0,0 +1,869 @@ +/* DLATRS.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Table of constant values */ + +static integer c__1 = 1; +static doublereal c_b36 = .5; + +/* Subroutine */ int dlatrs_(uplo, trans, diag, normin, n, a, lda, x, scale, + cnorm, info, uplo_len, trans_len, diag_len, normin_len) +char *uplo, *trans, *diag, *normin; +integer *n; +doublereal *a; +integer *lda; +doublereal *x, *scale, *cnorm; +integer *info; +ftnlen uplo_len; +ftnlen trans_len; +ftnlen diag_len; +ftnlen normin_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2, i__3; + doublereal d__1, d__2, d__3; + + /* Local variables */ + static integer jinc; + extern doublereal ddot_(); + static doublereal xbnd; + static integer imax; + static doublereal tmax, tjjs, xmax, grow, sumj; + static integer i, j; + extern /* Subroutine */ int dscal_(); + extern logical lsame_(); + static doublereal tscal, uscal; + extern doublereal dasum_(); + static integer jlast; + extern /* Subroutine */ int daxpy_(); + static logical upper; + extern /* Subroutine */ int dtrsv_(); + extern doublereal dlamch_(); + static doublereal xj; + extern integer idamax_(); + extern /* Subroutine */ int xerbla_(); + static doublereal bignum; + static logical notran; + static integer jfirst; + static doublereal smlnum; + static logical nounit; + static doublereal rec, tjj; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* June 30, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DLATRS solves one of the triangular systems */ + +/* A *x = s*b or A'*x = s*b */ + +/* with scaling to prevent overflow. Here A is an upper or lower */ +/* triangular matrix, A' denotes the transpose of A, x and b are */ +/* n-element vectors, and s is a scaling factor, usually less than */ +/* or equal to 1, chosen so that the components of x will be less than */ +/* the overflow threshold. If the unscaled problem will not cause */ +/* overflow, the Level 2 BLAS routine DTRSV is called. If the matrix A +*/ +/* is singular (A(j,j) = 0 for some j), then s is set to 0 and a */ +/* non-trivial solution to A*x = 0 is returned. */ + +/* Arguments */ +/* ========= */ + +/* UPLO (input) CHARACTER*1 */ +/* Specifies whether the matrix A is upper or lower triangular. +*/ +/* = 'U': Upper triangular */ +/* = 'L': Lower triangular */ + +/* TRANS (input) CHARACTER*1 */ +/* Specifies the operation applied to A. */ +/* = 'N': Solve A * x = s*b (No transpose) */ +/* = 'T': Solve A'* x = s*b (Transpose) */ +/* = 'C': Solve A'* x = s*b (Conjugate transpose = Transpose) +*/ + +/* DIAG (input) CHARACTER*1 */ +/* Specifies whether or not the matrix A is unit triangular. */ +/* = 'N': Non-unit triangular */ +/* = 'U': Unit triangular */ + +/* NORMIN (input) CHARACTER*1 */ +/* Specifies whether CNORM has been set or not. */ +/* = 'Y': CNORM contains the column norms on entry */ +/* = 'N': CNORM is not set on entry. On exit, the norms will */ +/* be computed and stored in CNORM. */ + +/* N (input) INTEGER */ +/* The order of the matrix A. N >= 0. */ + +/* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ +/* The triangular matrix A. If UPLO = 'U', the leading n by n */ +/* upper triangular part of the array A contains the upper */ +/* triangular matrix, and the strictly lower triangular part of +*/ +/* A is not referenced. If UPLO = 'L', the leading n by n lower +*/ +/* triangular part of the array A contains the lower triangular +*/ +/* matrix, and the strictly upper triangular part of A is not */ +/* referenced. If DIAG = 'U', the diagonal elements of A are */ +/* also not referenced and are assumed to be 1. */ + +/* LDA (input) INTEGER */ +/* The leading dimension of the array A. LDA >= max (1,N). */ + +/* X (input/output) DOUBLE PRECISION array, dimension (N) */ +/* On entry, the right hand side b of the triangular system. */ +/* On exit, X is overwritten by the solution vector x. */ + +/* SCALE (output) DOUBLE PRECISION */ +/* The scaling factor s for the triangular system */ +/* A * x = s*b or A'* x = s*b. */ +/* If SCALE = 0, the matrix A is singular or badly scaled, and */ +/* the vector x is an exact or approximate solution to A*x = 0. +*/ + +/* CNORM (input or output) DOUBLE PRECISION array, dimension (N) */ + +/* If NORMIN = 'Y', CNORM is an input variable and CNORM(j) */ +/* contains the norm of the off-diagonal part of the j-th column +*/ +/* of A. If TRANS = 'N', CNORM(j) must be greater than or equal +*/ +/* to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j) */ +/* must be greater than or equal to the 1-norm. */ + +/* If NORMIN = 'N', CNORM is an output variable and CNORM(j) */ +/* returns the 1-norm of the offdiagonal part of the j-th column +*/ +/* of A. */ + +/* INFO (output) INTEGER */ +/* = 0: successful exit */ +/* < 0: if INFO = -k, the k-th argument had an illegal value */ + +/* Further Details */ +/* ======= ======= */ + +/* A rough bound on x is computed; if that is less than overflow, DTRSV +*/ +/* is called, otherwise, specific code is used which checks for possible +*/ +/* overflow or divide-by-zero at every operation. */ + +/* A columnwise scheme is used for solving A*x = b. The basic algorithm +*/ +/* if A is lower triangular is */ + +/* x[1:n] := b[1:n] */ +/* for j = 1, ..., n */ +/* x(j) := x(j) / A(j,j) */ +/* x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j] */ +/* end */ + +/* Define bounds on the components of x after j iterations of the loop: +*/ +/* M(j) = bound on x[1:j] */ +/* G(j) = bound on x[j+1:n] */ +/* Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}. */ + +/* Then for iteration j+1 we have */ +/* M(j+1) <= G(j) / | A(j+1,j+1) | */ +/* G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] | */ +/* <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | ) */ + +/* where CNORM(j+1) is greater than or equal to the infinity-norm of */ +/* column j+1 of A, not counting the diagonal. Hence */ + +/* G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | ) */ +/* 1<=i<=j */ +/* and */ + +/* |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| ) +*/ +/* 1<=i< j */ + +/* Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTRSV if the */ +/* reciprocal of the largest M(j), j=1,..,n, is larger than */ +/* max(underflow, 1/overflow). */ + +/* The bound on x(j) is also used to determine when a step in the */ +/* columnwise method can be performed without fear of overflow. If */ +/* the computed bound is greater than a large constant, x is scaled to */ +/* prevent overflow, but if the bound overflows, x is set to 0, x(j) to +*/ +/* 1, and scale to 0, and a non-trivial solution to A*x = 0 is found. */ + +/* Similarly, a row-wise scheme is used to solve A'*x = b. The basic */ +/* algorithm for A upper triangular is */ + +/* for j = 1, ..., n */ +/* x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j) */ +/* end */ + +/* We simultaneously compute two bounds */ +/* G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j */ +/* M(j) = bound on x(i), 1<=i<=j */ + +/* The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we */ +/* add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1. */ +/* Then the bound on x(j) is */ + +/* M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) | */ + +/* <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| ) */ +/* 1<=i<=j */ + +/* and we can safely call DTRSV if 1/M(n) and 1/G(n) are both greater */ +/* than max(underflow, 1/overflow). */ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --x; + --cnorm; + + /* Function Body */ + *info = 0; + upper = lsame_(uplo, "U", 1L, 1L); + notran = lsame_(trans, "N", 1L, 1L); + nounit = lsame_(diag, "N", 1L, 1L); + +/* Test the input parameters. */ + + if (! upper && ! lsame_(uplo, "L", 1L, 1L)) { + *info = -1; + } else if (! notran && ! lsame_(trans, "T", 1L, 1L) && ! lsame_(trans, + "C", 1L, 1L)) { + *info = -2; + } else if (! nounit && ! lsame_(diag, "U", 1L, 1L)) { + *info = -3; + } else if (! lsame_(normin, "Y", 1L, 1L) && ! lsame_(normin, "N", 1L, 1L)) + { + *info = -4; + } else if (*n < 0) { + *info = -5; + } else if (*lda < max(1,*n)) { + *info = -7; + } + if (*info != 0) { + i__1 = -(*info); + xerbla_("DLATRS", &i__1, 6L); + return 0; + } + +/* Quick return if possible */ + + if (*n == 0) { + return 0; + } + +/* Determine machine dependent parameters to control overflow. */ + + smlnum = dlamch_("Safe minimum", 12L) / dlamch_("Precision", 9L); + bignum = 1. / smlnum; + *scale = 1.; + + if (lsame_(normin, "N", 1L, 1L)) { + +/* Compute the 1-norm of each column, not including the diagona +l. */ + + if (upper) { + +/* A is upper triangular. */ + + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = j - 1; + cnorm[j] = dasum_(&i__2, &a[j * a_dim1 + 1], &c__1); +/* L10: */ + } + } else { + +/* A is lower triangular. */ + + i__1 = *n - 1; + for (j = 1; j <= i__1; ++j) { + i__2 = *n - j; + cnorm[j] = dasum_(&i__2, &a[j + 1 + j * a_dim1], &c__1); +/* L20: */ + } + cnorm[*n] = 0.; + } + } + +/* Scale the column norms by TSCAL if the maximum entry in CNORM is */ +/* greater than BIGNUM. */ + + imax = idamax_(n, &cnorm[1], &c__1); + tmax = cnorm[imax]; + if (tmax <= bignum) { + tscal = 1.; + } else { + tscal = 1. / (smlnum * tmax); + dscal_(n, &tscal, &cnorm[1], &c__1); + } + +/* Compute a bound on the computed solution vector to see if the */ +/* Level 2 BLAS routine DTRSV can be used. */ + + j = idamax_(n, &x[1], &c__1); + xmax = (d__1 = x[j], abs(d__1)); + xbnd = xmax; + if (notran) { + +/* Compute the growth in A * x = b. */ + + if (upper) { + jfirst = *n; + jlast = 1; + jinc = -1; + } else { + jfirst = 1; + jlast = *n; + jinc = 1; + } + + if (tscal != 1.) { + grow = 0.; + goto L50; + } + + if (nounit) { + +/* A is non-unit triangular. */ + +/* Compute GROW = 1/G(j) and XBND = 1/M(j). */ +/* Initially, G(0) = max{x(i), i=1,...,n}. */ + + grow = 1. / max(xbnd,smlnum); + xbnd = grow; + i__1 = jlast; + i__2 = jinc; + for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { + +/* Exit the loop if the growth factor is too smal +l. */ + + if (grow <= smlnum) { + goto L50; + } + +/* M(j) = G(j-1) / abs(A(j,j)) */ + + tjj = (d__1 = a[j + j * a_dim1], abs(d__1)); +/* Computing MIN */ + d__1 = xbnd, d__2 = min(1.,tjj) * grow; + xbnd = min(d__1,d__2); + if (tjj + cnorm[j] >= smlnum) { + +/* G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j, +j)) ) */ + + grow *= tjj / (tjj + cnorm[j]); + } else { + +/* G(j) could overflow, set GROW to 0. */ + + grow = 0.; + } +/* L30: */ + } + grow = xbnd; + } else { + +/* A is unit triangular. */ + +/* Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,... +,n}. */ + +/* Computing MIN */ + d__1 = 1., d__2 = 1. / max(xbnd,smlnum); + grow = min(d__1,d__2); + i__2 = jlast; + i__1 = jinc; + for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { + +/* Exit the loop if the growth factor is too smal +l. */ + + if (grow <= smlnum) { + goto L50; + } + +/* G(j) = G(j-1)*( 1 + CNORM(j) ) */ + + grow *= 1. / (cnorm[j] + 1.); +/* L40: */ + } + } +L50: + + ; + } else { + +/* Compute the growth in A' * x = b. */ + + if (upper) { + jfirst = 1; + jlast = *n; + jinc = 1; + } else { + jfirst = *n; + jlast = 1; + jinc = -1; + } + + if (tscal != 1.) { + grow = 0.; + goto L80; + } + + if (nounit) { + +/* A is non-unit triangular. */ + +/* Compute GROW = 1/G(j) and XBND = 1/M(j). */ +/* Initially, M(0) = max{x(i), i=1,...,n}. */ + + grow = 1. / max(xbnd,smlnum); + xbnd = grow; + i__1 = jlast; + i__2 = jinc; + for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { + +/* Exit the loop if the growth factor is too smal +l. */ + + if (grow <= smlnum) { + goto L80; + } + +/* G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) ) +*/ + + xj = cnorm[j] + 1.; +/* Computing MIN */ + d__1 = grow, d__2 = xbnd / xj; + grow = min(d__1,d__2); + +/* M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j)) +*/ + + tjj = (d__1 = a[j + j * a_dim1], abs(d__1)); + if (xj > tjj) { + xbnd *= tjj / xj; + } +/* L60: */ + } + grow = min(grow,xbnd); + } else { + +/* A is unit triangular. */ + +/* Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,... +,n}. */ + +/* Computing MIN */ + d__1 = 1., d__2 = 1. / max(xbnd,smlnum); + grow = min(d__1,d__2); + i__2 = jlast; + i__1 = jinc; + for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { + +/* Exit the loop if the growth factor is too smal +l. */ + + if (grow <= smlnum) { + goto L80; + } + +/* G(j) = ( 1 + CNORM(j) )*G(j-1) */ + + xj = cnorm[j] + 1.; + grow /= xj; +/* L70: */ + } + } +L80: + ; + } + + if (grow * tscal > smlnum) { + +/* Use the Level 2 BLAS solve if the reciprocal of the bound on + */ +/* elements of X is not too small. */ + + dtrsv_(uplo, trans, diag, n, &a[a_offset], lda, &x[1], &c__1, 1L, 1L, + 1L); + } else { + +/* Use a Level 1 BLAS solve, scaling intermediate results. */ + + if (xmax > bignum) { + +/* Scale X so that its components are less than or equal + to */ +/* BIGNUM in absolute value. */ + + *scale = bignum / xmax; + dscal_(n, scale, &x[1], &c__1); + xmax = bignum; + } + + if (notran) { + +/* Solve A * x = b */ + + i__1 = jlast; + i__2 = jinc; + for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) { + +/* Compute x(j) = b(j) / A(j,j), scaling x if nec +essary. */ + + xj = (d__1 = x[j], abs(d__1)); + if (nounit) { + tjjs = a[j + j * a_dim1] * tscal; + } else { + tjjs = tscal; + if (tscal == 1.) { + goto L100; + } + } + tjj = abs(tjjs); + if (tjj > smlnum) { + +/* abs(A(j,j)) > SMLNUM: */ + + if (tjj < 1.) { + if (xj > tjj * bignum) { + +/* Scale x by 1/b(j). */ + + rec = 1. / xj; + dscal_(n, &rec, &x[1], &c__1); + *scale *= rec; + xmax *= rec; + } + } + x[j] /= tjjs; + xj = (d__1 = x[j], abs(d__1)); + } else if (tjj > 0.) { + +/* 0 < abs(A(j,j)) <= SMLNUM: */ + + if (xj > tjj * bignum) { + +/* Scale x by (1/abs(x(j)))*abs( +A(j,j))*BIGNUM */ +/* to avoid overflow when dividi +ng by A(j,j). */ + + rec = tjj * bignum / xj; + if (cnorm[j] > 1.) { + +/* Scale by 1/CNORM(j) to + avoid overflow when */ +/* multiplying x(j) times + column j. */ + + rec /= cnorm[j]; + } + dscal_(n, &rec, &x[1], &c__1); + *scale *= rec; + xmax *= rec; + } + x[j] /= tjjs; + xj = (d__1 = x[j], abs(d__1)); + } else { + +/* A(j,j) = 0: Set x(1:n) = 0, x(j) = +1, and */ +/* scale = 0, and compute a solution to + A*x = 0. */ + + i__3 = *n; + for (i = 1; i <= i__3; ++i) { + x[i] = 0.; +/* L90: */ + } + x[j] = 1.; + xj = 1.; + *scale = 0.; + xmax = 0.; + } +L100: + +/* Scale x if necessary to avoid overflow when ad +ding a */ +/* multiple of column j of A. */ + + if (xj > 1.) { + rec = 1. / xj; + if (cnorm[j] > (bignum - xmax) * rec) { + +/* Scale x by 1/(2*abs(x(j))). */ + + rec *= .5; + dscal_(n, &rec, &x[1], &c__1); + *scale *= rec; + } + } else if (xj * cnorm[j] > bignum - xmax) { + +/* Scale x by 1/2. */ + + dscal_(n, &c_b36, &x[1], &c__1); + *scale *= .5; + } + + if (upper) { + if (j > 1) { + +/* Compute the update */ +/* x(1:j-1) := x(1:j-1) - x(j) * + A(1:j-1,j) */ + + i__3 = j - 1; + d__1 = -x[j] * tscal; + daxpy_(&i__3, &d__1, &a[j * a_dim1 + 1], &c__1, &x[1], + &c__1); + i__3 = j - 1; + i = idamax_(&i__3, &x[1], &c__1); + xmax = (d__1 = x[i], abs(d__1)); + } + } else { + if (j < *n) { + +/* Compute the update */ +/* x(j+1:n) := x(j+1:n) - x(j) * + A(j+1:n,j) */ + + i__3 = *n - j; + d__1 = -x[j] * tscal; + daxpy_(&i__3, &d__1, &a[j + 1 + j * a_dim1], &c__1, & + x[j + 1], &c__1); + i__3 = *n - j; + i = j + idamax_(&i__3, &x[j + 1], &c__1); + xmax = (d__1 = x[i], abs(d__1)); + } + } +/* L110: */ + } + + } else { + +/* Solve A' * x = b */ + + i__2 = jlast; + i__1 = jinc; + for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) { + +/* Compute x(j) = b(j) - sum A(k,j)*x(k). */ +/* k<>j */ + + xj = (d__1 = x[j], abs(d__1)); + uscal = tscal; + rec = 1. / max(xmax,1.); + if (cnorm[j] > (bignum - xj) * rec) { + +/* If x(j) could overflow, scale x by 1/(2 +*XMAX). */ + + rec *= .5; + if (nounit) { + tjjs = a[j + j * a_dim1] * tscal; + } else { + tjjs = tscal; + } + tjj = abs(tjjs); + if (tjj > 1.) { + +/* Divide by A(j,j) when scaling + x if A(j,j) > 1. */ + +/* Computing MIN */ + d__1 = 1., d__2 = rec * tjj; + rec = min(d__1,d__2); + uscal /= tjjs; + } + if (rec < 1.) { + dscal_(n, &rec, &x[1], &c__1); + *scale *= rec; + xmax *= rec; + } + } + + sumj = 0.; + if (uscal == 1.) { + +/* If the scaling needed for A in the dot +product is 1, */ +/* call DDOT to perform the dot product. +*/ + + if (upper) { + i__3 = j - 1; + sumj = ddot_(&i__3, &a[j * a_dim1 + 1], &c__1, &x[1], + &c__1); + } else if (j < *n) { + i__3 = *n - j; + sumj = ddot_(&i__3, &a[j + 1 + j * a_dim1], &c__1, &x[ + j + 1], &c__1); + } + } else { + +/* Otherwise, use in-line code for the dot + product. */ + + if (upper) { + i__3 = j - 1; + for (i = 1; i <= i__3; ++i) { + sumj += a[i + j * a_dim1] * uscal * x[i]; +/* L120: */ + } + } else if (j < *n) { + i__3 = *n; + for (i = j + 1; i <= i__3; ++i) { + sumj += a[i + j * a_dim1] * uscal * x[i]; +/* L130: */ + } + } + } + + if (uscal == tscal) { + +/* Compute x(j) := ( x(j) - sumj ) / A(j,j +) if 1/A(j,j) */ +/* was not used to scale the dotproduct. +*/ + + x[j] -= sumj; + xj = (d__1 = x[j], abs(d__1)); + if (nounit) { + tjjs = a[j + j * a_dim1] * tscal; + } else { + tjjs = tscal; + if (tscal == 1.) { + goto L150; + } + } + +/* Compute x(j) = x(j) / A(j,j), scalin +g if necessary. */ + + tjj = abs(tjjs); + if (tjj > smlnum) { + +/* abs(A(j,j)) > SMLNUM: */ + + if (tjj < 1.) { + if (xj > tjj * bignum) { + +/* Scale X by 1/ab +s(x(j)). */ + + rec = 1. / xj; + dscal_(n, &rec, &x[1], &c__1); + *scale *= rec; + xmax *= rec; + } + } + x[j] /= tjjs; + } else if (tjj > 0.) { + +/* 0 < abs(A(j,j)) <= SMLNUM: */ + + if (xj > tjj * bignum) { + +/* Scale x by (1/abs(x(j) +))*abs(A(j,j))*BIGNUM. */ + + rec = tjj * bignum / xj; + dscal_(n, &rec, &x[1], &c__1); + *scale *= rec; + xmax *= rec; + } + x[j] /= tjjs; + } else { + +/* A(j,j) = 0: Set x(1:n) = 0, +x(j) = 1, and */ +/* scale = 0, and compute a solu +tion to A'*x = 0. */ + + i__3 = *n; + for (i = 1; i <= i__3; ++i) { + x[i] = 0.; +/* L140: */ + } + x[j] = 1.; + *scale = 0.; + xmax = 0.; + } +L150: + ; + } else { + +/* Compute x(j) := x(j) / A(j,j) - sumj i +f the dot */ +/* product has already been divided by 1/A +(j,j). */ + + x[j] = x[j] / tjjs - sumj; + } +/* Computing MAX */ + d__2 = xmax, d__3 = (d__1 = x[j], abs(d__1)); + xmax = max(d__2,d__3); +/* L160: */ + } + } + *scale /= tscal; + } + +/* Scale the column norms by 1/TSCAL for return. */ + + if (tscal != 1.) { + d__1 = 1. / tscal; + dscal_(n, &d__1, &cnorm[1], &c__1); + } + + return 0; + +/* End of DLATRS */ + +} /* dlatrs_ */ + diff --git a/src/matrix/camlapack/drscl.c b/src/matrix/camlapack/drscl.c new file mode 100644 index 0000000..1aeaf2b --- /dev/null +++ b/src/matrix/camlapack/drscl.c @@ -0,0 +1,135 @@ +/* DRSCL.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +/* Subroutine */ int drscl_(n, sa, sx, incx) +integer *n; +doublereal *sa, *sx; +integer *incx; +{ + static doublereal cden; + static logical done; + static doublereal cnum, cden1, cnum1; + extern /* Subroutine */ int dscal_(), dlabad_(); + extern doublereal dlamch_(); + static doublereal bignum, smlnum, mul; + + +/* -- LAPACK auxiliary routine (version 1.1) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* October 31, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DRSCL multiplies an n-element real vector x by the real scalar 1/a. */ +/* This is done without overflow or underflow as long as */ +/* the final result x/a does not overflow or underflow. */ + +/* Arguments */ +/* ========= */ + +/* N (input) INTEGER */ +/* The number of components of the vector x. */ + +/* SA (input) DOUBLE PRECISION */ +/* The scalar a which is used to divide each component of x. */ +/* SA must be >= 0, or the subroutine will divide by zero. */ + +/* SX (input/output) DOUBLE PRECISION array, dimension */ +/* (1+(N-1)*abs(INCX)) */ +/* The n-element vector x. */ + +/* INCX (input) INTEGER */ +/* The increment between successive values of the vector SX. */ +/* > 0: SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i), 1< i<= n +*/ +/* < 0: SX(1) = X(n) and SX(1+(i-1)*INCX) = x(n-i+1), 1< i<= n +*/ + +/* ===================================================================== +*/ + +/* .. Parameters .. */ +/* .. */ +/* .. Local Scalars .. */ +/* .. */ +/* .. External Functions .. */ +/* .. */ +/* .. External Subroutines .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Quick return if possible */ + + /* Parameter adjustments */ + --sx; + + /* Function Body */ + if (*n <= 0) { + return 0; + } + +/* Get machine parameters */ + + smlnum = dlamch_("S", 1L); + bignum = 1. / smlnum; + dlabad_(&smlnum, &bignum); + +/* Initialize the denominator to SA and the numerator to 1. */ + + cden = *sa; + cnum = 1.; + +L10: + cden1 = cden * smlnum; + cnum1 = cnum / bignum; + if (abs(cden1) > abs(cnum) && cnum != 0.) { + +/* Pre-multiply X by SMLNUM if CDEN is large compared to CNUM. +*/ + + mul = smlnum; + done = FALSE_; + cden = cden1; + } else if (abs(cnum1) > abs(cden)) { + +/* Pre-multiply X by BIGNUM if CDEN is small compared to CNUM. +*/ + + mul = bignum; + done = FALSE_; + cnum = cnum1; + } else { + +/* Multiply X by CNUM / CDEN and return. */ + + mul = cnum / cden; + done = TRUE_; + } + +/* Scale the vector X by MUL */ + + dscal_(n, &mul, &sx[1], incx); + + if (! done) { + goto L10; + } + + return 0; + +/* End of DRSCL */ + +} /* drscl_ */ + diff --git a/src/matrix/camlapack/dtrsm.c b/src/matrix/camlapack/dtrsm.c new file mode 100644 index 0000000..c66e798 --- /dev/null +++ b/src/matrix/camlapack/dtrsm.c @@ -0,0 +1,510 @@ +/* DTRSM.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + + +/* *********************************************************************** */ + +/* Subroutine */ int dtrsm_(side, uplo, transa, diag, m, n, alpha, a, lda, b, + ldb, side_len, uplo_len, transa_len, diag_len) +char *side, *uplo, *transa, *diag; +integer *m, *n; +doublereal *alpha, *a; +integer *lda; +doublereal *b; +integer *ldb; +ftnlen side_len; +ftnlen uplo_len; +ftnlen transa_len; +ftnlen diag_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3; + + /* Local variables */ + static integer info; + static doublereal temp; + static integer i, j, k; + static logical lside; + extern logical lsame_(); + static integer nrowa; + static logical upper; + extern /* Subroutine */ int xerbla_(); + static logical nounit; + +/* .. Scalar Arguments .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DTRSM solves one of the matrix equations */ + +/* op( A )*X = alpha*B, or X*op( A ) = alpha*B, */ + +/* where alpha is a scalar, X and B are m by n matrices, A is a unit, or +*/ +/* non-unit, upper or lower triangular matrix and op( A ) is one of +*/ + +/* op( A ) = A or op( A ) = A'. */ + +/* The matrix X is overwritten on B. */ + +/* Parameters */ +/* ========== */ + +/* SIDE - CHARACTER*1. */ +/* On entry, SIDE specifies whether op( A ) appears on the left +*/ +/* or right of X as follows: */ + +/* SIDE = 'L' or 'l' op( A )*X = alpha*B. */ + +/* SIDE = 'R' or 'r' X*op( A ) = alpha*B. */ + +/* Unchanged on exit. */ + +/* UPLO - CHARACTER*1. */ +/* On entry, UPLO specifies whether the matrix A is an upper or +*/ +/* lower triangular matrix as follows: */ + +/* UPLO = 'U' or 'u' A is an upper triangular matrix. */ + +/* UPLO = 'L' or 'l' A is a lower triangular matrix. */ + +/* Unchanged on exit. */ + +/* TRANSA - CHARACTER*1. */ +/* On entry, TRANSA specifies the form of op( A ) to be used in +*/ +/* the matrix multiplication as follows: */ + +/* TRANSA = 'N' or 'n' op( A ) = A. */ + +/* TRANSA = 'T' or 't' op( A ) = A'. */ + +/* TRANSA = 'C' or 'c' op( A ) = A'. */ + +/* Unchanged on exit. */ + +/* DIAG - CHARACTER*1. */ +/* On entry, DIAG specifies whether or not A is unit triangular +*/ +/* as follows: */ + +/* DIAG = 'U' or 'u' A is assumed to be unit triangular. */ + +/* DIAG = 'N' or 'n' A is not assumed to be unit */ +/* triangular. */ + +/* Unchanged on exit. */ + +/* M - INTEGER. */ +/* On entry, M specifies the number of rows of B. M must be at +*/ +/* least zero. */ +/* Unchanged on exit. */ + +/* N - INTEGER. */ +/* On entry, N specifies the number of columns of B. N must be +*/ +/* at least zero. */ +/* Unchanged on exit. */ + +/* ALPHA - DOUBLE PRECISION. */ +/* On entry, ALPHA specifies the scalar alpha. When alpha is +*/ +/* zero then A is not referenced and B need not be set before +*/ +/* entry. */ +/* Unchanged on exit. */ + +/* A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m +*/ +/* when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. +*/ +/* Before entry with UPLO = 'U' or 'u', the leading k by k +*/ +/* upper triangular part of the array A must contain the upper +*/ +/* triangular matrix and the strictly lower triangular part of +*/ +/* A is not referenced. */ +/* Before entry with UPLO = 'L' or 'l', the leading k by k +*/ +/* lower triangular part of the array A must contain the lower +*/ +/* triangular matrix and the strictly upper triangular part of +*/ +/* A is not referenced. */ +/* Note that when DIAG = 'U' or 'u', the diagonal elements of +*/ +/* A are not referenced either, but are assumed to be unity. +*/ +/* Unchanged on exit. */ + +/* LDA - INTEGER. */ +/* On entry, LDA specifies the first dimension of A as declared +*/ +/* in the calling (sub) program. When SIDE = 'L' or 'l' then +*/ +/* LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' +*/ +/* then LDA must be at least max( 1, n ). */ +/* Unchanged on exit. */ + +/* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ). */ +/* Before entry, the leading m by n part of the array B must +*/ +/* contain the right-hand side matrix B, and on exit is +*/ +/* overwritten by the solution matrix X. */ + +/* LDB - INTEGER. */ +/* On entry, LDB specifies the first dimension of B as declared +*/ +/* in the calling (sub) program. LDB must be at least +*/ +/* max( 1, m ). */ +/* Unchanged on exit. */ + + +/* Level 3 Blas routine. */ + + +/* -- Written on 8-February-1989. */ +/* Jack Dongarra, Argonne National Laboratory. */ +/* Iain Duff, AERE Harwell. */ +/* Jeremy Du Croz, Numerical Algorithms Group Ltd. */ +/* Sven Hammarling, Numerical Algorithms Group Ltd. */ + + +/* .. External Functions .. */ +/* .. External Subroutines .. */ +/* .. Intrinsic Functions .. */ +/* .. Local Scalars .. */ +/* .. Parameters .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + b_dim1 = *ldb; + b_offset = b_dim1 + 1; + b -= b_offset; + + /* Function Body */ + lside = lsame_(side, "L", 1L, 1L); + if (lside) { + nrowa = *m; + } else { + nrowa = *n; + } + nounit = lsame_(diag, "N", 1L, 1L); + upper = lsame_(uplo, "U", 1L, 1L); + + info = 0; + if (! lside && ! lsame_(side, "R", 1L, 1L)) { + info = 1; + } else if (! upper && ! lsame_(uplo, "L", 1L, 1L)) { + info = 2; + } else if (! lsame_(transa, "N", 1L, 1L) && ! lsame_(transa, "T", 1L, 1L) + && ! lsame_(transa, "C", 1L, 1L)) { + info = 3; + } else if (! lsame_(diag, "U", 1L, 1L) && ! lsame_(diag, "N", 1L, 1L)) { + info = 4; + } else if (*m < 0) { + info = 5; + } else if (*n < 0) { + info = 6; + } else if (*lda < max(1,nrowa)) { + info = 9; + } else if (*ldb < max(1,*m)) { + info = 11; + } + if (info != 0) { + xerbla_("DTRSM ", &info, 6L); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0) { + return 0; + } + +/* And when alpha.eq.zero. */ + + if (*alpha == 0.) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = 0.; +/* L10: */ + } +/* L20: */ + } + return 0; + } + +/* Start the operations. */ + + if (lside) { + if (lsame_(transa, "N", 1L, 1L)) { + +/* Form B := alpha*inv( A )*B. */ + + if (upper) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (*alpha != 1.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = *alpha * b[i + j * b_dim1]; +/* L30: */ + } + } + for (k = *m; k >= 1; --k) { + if (b[k + j * b_dim1] != 0.) { + if (nounit) { + b[k + j * b_dim1] /= a[k + k * a_dim1]; + } + i__2 = k - 1; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] -= b[k + j * b_dim1] * a[i + + k * a_dim1]; +/* L40: */ + } + } +/* L50: */ + } +/* L60: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (*alpha != 1.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = *alpha * b[i + j * b_dim1]; +/* L70: */ + } + } + i__2 = *m; + for (k = 1; k <= i__2; ++k) { + if (b[k + j * b_dim1] != 0.) { + if (nounit) { + b[k + j * b_dim1] /= a[k + k * a_dim1]; + } + i__3 = *m; + for (i = k + 1; i <= i__3; ++i) { + b[i + j * b_dim1] -= b[k + j * b_dim1] * a[i + + k * a_dim1]; +/* L80: */ + } + } +/* L90: */ + } +/* L100: */ + } + } + } else { + +/* Form B := alpha*inv( A' )*B. */ + + if (upper) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + temp = *alpha * b[i + j * b_dim1]; + i__3 = i - 1; + for (k = 1; k <= i__3; ++k) { + temp -= a[k + i * a_dim1] * b[k + j * b_dim1]; +/* L110: */ + } + if (nounit) { + temp /= a[i + i * a_dim1]; + } + b[i + j * b_dim1] = temp; +/* L120: */ + } +/* L130: */ + } + } else { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + for (i = *m; i >= 1; --i) { + temp = *alpha * b[i + j * b_dim1]; + i__2 = *m; + for (k = i + 1; k <= i__2; ++k) { + temp -= a[k + i * a_dim1] * b[k + j * b_dim1]; +/* L140: */ + } + if (nounit) { + temp /= a[i + i * a_dim1]; + } + b[i + j * b_dim1] = temp; +/* L150: */ + } +/* L160: */ + } + } + } + } else { + if (lsame_(transa, "N", 1L, 1L)) { + +/* Form B := alpha*B*inv( A ). */ + + if (upper) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (*alpha != 1.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = *alpha * b[i + j * b_dim1]; +/* L170: */ + } + } + i__2 = j - 1; + for (k = 1; k <= i__2; ++k) { + if (a[k + j * a_dim1] != 0.) { + i__3 = *m; + for (i = 1; i <= i__3; ++i) { + b[i + j * b_dim1] -= a[k + j * a_dim1] * b[i + + k * b_dim1]; +/* L180: */ + } + } +/* L190: */ + } + if (nounit) { + temp = 1. / a[j + j * a_dim1]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] = temp * b[i + j * b_dim1]; +/* L200: */ + } + } +/* L210: */ + } + } else { + for (j = *n; j >= 1; --j) { + if (*alpha != 1.) { + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + b[i + j * b_dim1] = *alpha * b[i + j * b_dim1]; +/* L220: */ + } + } + i__1 = *n; + for (k = j + 1; k <= i__1; ++k) { + if (a[k + j * a_dim1] != 0.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] -= a[k + j * a_dim1] * b[i + + k * b_dim1]; +/* L230: */ + } + } +/* L240: */ + } + if (nounit) { + temp = 1. / a[j + j * a_dim1]; + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + b[i + j * b_dim1] = temp * b[i + j * b_dim1]; +/* L250: */ + } + } +/* L260: */ + } + } + } else { + +/* Form B := alpha*B*inv( A' ). */ + + if (upper) { + for (k = *n; k >= 1; --k) { + if (nounit) { + temp = 1. / a[k + k * a_dim1]; + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + b[i + k * b_dim1] = temp * b[i + k * b_dim1]; +/* L270: */ + } + } + i__1 = k - 1; + for (j = 1; j <= i__1; ++j) { + if (a[j + k * a_dim1] != 0.) { + temp = a[j + k * a_dim1]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + j * b_dim1] -= temp * b[i + k * b_dim1]; +/* L280: */ + } + } +/* L290: */ + } + if (*alpha != 1.) { + i__1 = *m; + for (i = 1; i <= i__1; ++i) { + b[i + k * b_dim1] = *alpha * b[i + k * b_dim1]; +/* L300: */ + } + } +/* L310: */ + } + } else { + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + if (nounit) { + temp = 1. / a[k + k * a_dim1]; + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + k * b_dim1] = temp * b[i + k * b_dim1]; +/* L320: */ + } + } + i__2 = *n; + for (j = k + 1; j <= i__2; ++j) { + if (a[j + k * a_dim1] != 0.) { + temp = a[j + k * a_dim1]; + i__3 = *m; + for (i = 1; i <= i__3; ++i) { + b[i + j * b_dim1] -= temp * b[i + k * b_dim1]; +/* L330: */ + } + } +/* L340: */ + } + if (*alpha != 1.) { + i__2 = *m; + for (i = 1; i <= i__2; ++i) { + b[i + k * b_dim1] = *alpha * b[i + k * b_dim1]; +/* L350: */ + } + } +/* L360: */ + } + } + } + } + + return 0; + +/* End of DTRSM . */ + +} /* dtrsm_ */ + diff --git a/src/matrix/camlapack/dtrsv.c b/src/matrix/camlapack/dtrsv.c new file mode 100644 index 0000000..3a3436a --- /dev/null +++ b/src/matrix/camlapack/dtrsv.c @@ -0,0 +1,357 @@ +/* DTRSV.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + + +/* *********************************************************************** */ + +/* Subroutine */ int dtrsv_(uplo, trans, diag, n, a, lda, x, incx, uplo_len, + trans_len, diag_len) +char *uplo, *trans, *diag; +integer *n; +doublereal *a; +integer *lda; +doublereal *x; +integer *incx; +ftnlen uplo_len; +ftnlen trans_len; +ftnlen diag_len; +{ + /* System generated locals */ + integer a_dim1, a_offset, i__1, i__2; + + /* Local variables */ + static integer info; + static doublereal temp; + static integer i, j; + extern logical lsame_(); + static integer ix, jx, kx; + extern /* Subroutine */ int xerbla_(); + static logical nounit; + +/* .. Scalar Arguments .. */ +/* .. Array Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* DTRSV solves one of the systems of equations */ + +/* A*x = b, or A'*x = b, */ + +/* where b and x are n element vectors and A is an n by n unit, or */ +/* non-unit, upper or lower triangular matrix. */ + +/* No test for singularity or near-singularity is included in this */ +/* routine. Such tests must be performed before calling this routine. */ + +/* Parameters */ +/* ========== */ + +/* UPLO - CHARACTER*1. */ +/* On entry, UPLO specifies whether the matrix is an upper or */ +/* lower triangular matrix as follows: */ + +/* UPLO = 'U' or 'u' A is an upper triangular matrix. */ + +/* UPLO = 'L' or 'l' A is a lower triangular matrix. */ + +/* Unchanged on exit. */ + +/* TRANS - CHARACTER*1. */ +/* On entry, TRANS specifies the equations to be solved as */ +/* follows: */ + +/* TRANS = 'N' or 'n' A*x = b. */ + +/* TRANS = 'T' or 't' A'*x = b. */ + +/* TRANS = 'C' or 'c' A'*x = b. */ + +/* Unchanged on exit. */ + +/* DIAG - CHARACTER*1. */ +/* On entry, DIAG specifies whether or not A is unit */ +/* triangular as follows: */ + +/* DIAG = 'U' or 'u' A is assumed to be unit triangular. */ + +/* DIAG = 'N' or 'n' A is not assumed to be unit */ +/* triangular. */ + +/* Unchanged on exit. */ + +/* N - INTEGER. */ +/* On entry, N specifies the order of the matrix A. */ +/* N must be at least zero. */ +/* Unchanged on exit. */ + +/* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). */ +/* Before entry with UPLO = 'U' or 'u', the leading n by n */ +/* upper triangular part of the array A must contain the upper +*/ +/* triangular matrix and the strictly lower triangular part of +*/ +/* A is not referenced. */ +/* Before entry with UPLO = 'L' or 'l', the leading n by n */ +/* lower triangular part of the array A must contain the lower +*/ +/* triangular matrix and the strictly upper triangular part of +*/ +/* A is not referenced. */ +/* Note that when DIAG = 'U' or 'u', the diagonal elements of +*/ +/* A are not referenced either, but are assumed to be unity. */ +/* Unchanged on exit. */ + +/* LDA - INTEGER. */ +/* On entry, LDA specifies the first dimension of A as declared +*/ +/* in the calling (sub) program. LDA must be at least */ +/* max( 1, n ). */ +/* Unchanged on exit. */ + +/* X - DOUBLE PRECISION array of dimension at least */ +/* ( 1 + ( n - 1 )*abs( INCX ) ). */ +/* Before entry, the incremented array X must contain the n */ +/* element right-hand side vector b. On exit, X is overwritten +*/ +/* with the solution vector x. */ + +/* INCX - INTEGER. */ +/* On entry, INCX specifies the increment for the elements of */ +/* X. INCX must not be zero. */ +/* Unchanged on exit. */ + + +/* Level 2 Blas routine. */ + +/* -- Written on 22-October-1986. */ +/* Jack Dongarra, Argonne National Lab. */ +/* Jeremy Du Croz, Nag Central Office. */ +/* Sven Hammarling, Nag Central Office. */ +/* Richard Hanson, Sandia National Labs. */ + + +/* .. Parameters .. */ +/* .. Local Scalars .. */ +/* .. External Functions .. */ +/* .. External Subroutines .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + +/* Test the input parameters. */ + + /* Parameter adjustments */ + a_dim1 = *lda; + a_offset = a_dim1 + 1; + a -= a_offset; + --x; + + /* Function Body */ + info = 0; + if (! lsame_(uplo, "U", 1L, 1L) && ! lsame_(uplo, "L", 1L, 1L)) { + info = 1; + } else if (! lsame_(trans, "N", 1L, 1L) && ! lsame_(trans, "T", 1L, 1L) && + ! lsame_(trans, "C", 1L, 1L)) { + info = 2; + } else if (! lsame_(diag, "U", 1L, 1L) && ! lsame_(diag, "N", 1L, 1L)) { + info = 3; + } else if (*n < 0) { + info = 4; + } else if (*lda < max(1,*n)) { + info = 6; + } else if (*incx == 0) { + info = 8; + } + if (info != 0) { + xerbla_("DTRSV ", &info, 6L); + return 0; + } + +/* Quick return if possible. */ + + if (*n == 0) { + return 0; + } + + nounit = lsame_(diag, "N", 1L, 1L); + +/* Set up the start point in X if the increment is not unity. This */ +/* will be ( N - 1 )*INCX too small for descending loops. */ + + if (*incx <= 0) { + kx = 1 - (*n - 1) * *incx; + } else if (*incx != 1) { + kx = 1; + } + +/* Start the operations. In this version the elements of A are */ +/* accessed sequentially with one pass through A. */ + + if (lsame_(trans, "N", 1L, 1L)) { + +/* Form x := inv( A )*x. */ + + if (lsame_(uplo, "U", 1L, 1L)) { + if (*incx == 1) { + for (j = *n; j >= 1; --j) { + if (x[j] != 0.) { + if (nounit) { + x[j] /= a[j + j * a_dim1]; + } + temp = x[j]; + for (i = j - 1; i >= 1; --i) { + x[i] -= temp * a[i + j * a_dim1]; +/* L10: */ + } + } +/* L20: */ + } + } else { + jx = kx + (*n - 1) * *incx; + for (j = *n; j >= 1; --j) { + if (x[jx] != 0.) { + if (nounit) { + x[jx] /= a[j + j * a_dim1]; + } + temp = x[jx]; + ix = jx; + for (i = j - 1; i >= 1; --i) { + ix -= *incx; + x[ix] -= temp * a[i + j * a_dim1]; +/* L30: */ + } + } + jx -= *incx; +/* L40: */ + } + } + } else { + if (*incx == 1) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (x[j] != 0.) { + if (nounit) { + x[j] /= a[j + j * a_dim1]; + } + temp = x[j]; + i__2 = *n; + for (i = j + 1; i <= i__2; ++i) { + x[i] -= temp * a[i + j * a_dim1]; +/* L50: */ + } + } +/* L60: */ + } + } else { + jx = kx; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (x[jx] != 0.) { + if (nounit) { + x[jx] /= a[j + j * a_dim1]; + } + temp = x[jx]; + ix = jx; + i__2 = *n; + for (i = j + 1; i <= i__2; ++i) { + ix += *incx; + x[ix] -= temp * a[i + j * a_dim1]; +/* L70: */ + } + } + jx += *incx; +/* L80: */ + } + } + } + } else { + +/* Form x := inv( A' )*x. */ + + if (lsame_(uplo, "U", 1L, 1L)) { + if (*incx == 1) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + temp = x[j]; + i__2 = j - 1; + for (i = 1; i <= i__2; ++i) { + temp -= a[i + j * a_dim1] * x[i]; +/* L90: */ + } + if (nounit) { + temp /= a[j + j * a_dim1]; + } + x[j] = temp; +/* L100: */ + } + } else { + jx = kx; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + temp = x[jx]; + ix = kx; + i__2 = j - 1; + for (i = 1; i <= i__2; ++i) { + temp -= a[i + j * a_dim1] * x[ix]; + ix += *incx; +/* L110: */ + } + if (nounit) { + temp /= a[j + j * a_dim1]; + } + x[jx] = temp; + jx += *incx; +/* L120: */ + } + } + } else { + if (*incx == 1) { + for (j = *n; j >= 1; --j) { + temp = x[j]; + i__1 = j + 1; + for (i = *n; i >= i__1; --i) { + temp -= a[i + j * a_dim1] * x[i]; +/* L130: */ + } + if (nounit) { + temp /= a[j + j * a_dim1]; + } + x[j] = temp; +/* L140: */ + } + } else { + kx += (*n - 1) * *incx; + jx = kx; + for (j = *n; j >= 1; --j) { + temp = x[jx]; + ix = kx; + i__1 = j + 1; + for (i = *n; i >= i__1; --i) { + temp -= a[i + j * a_dim1] * x[ix]; + ix -= *incx; +/* L150: */ + } + if (nounit) { + temp /= a[j + j * a_dim1]; + } + x[jx] = temp; + jx -= *incx; +/* L160: */ + } + } + } + } + + return 0; + +/* End of DTRSV . */ + +} /* dtrsv_ */ + diff --git a/src/matrix/camlapack/f2c.h b/src/matrix/camlapack/f2c.h new file mode 100644 index 0000000..b044eb3 --- /dev/null +++ b/src/matrix/camlapack/f2c.h @@ -0,0 +1,214 @@ +/* f2c.h -- Standard Fortran to C header file */ + +/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." + + - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ + +#ifndef F2C_INCLUDE +#define F2C_INCLUDE + +typedef long int integer; +typedef char *address; +typedef short int shortint; +typedef float real; +typedef double doublereal; +typedef struct { real r, i; } complex; +typedef struct { doublereal r, i; } doublecomplex; +typedef long int logical; +typedef short int shortlogical; +typedef char logical1; +typedef char integer1; +/* typedef long long longint; */ /* system-dependent */ + +#define TRUE_ (1) +#define FALSE_ (0) + +/* Extern is for use with -E */ +#ifndef Extern +#define Extern extern +#endif + +/* I/O stuff */ + +#ifdef f2c_i2 +/* for -i2 */ +typedef short flag; +typedef short ftnlen; +typedef short ftnint; +#else +typedef long int flag; +typedef long int ftnlen; +typedef long int ftnint; +#endif + +/*external read, write*/ +typedef struct +{ flag cierr; + ftnint ciunit; + flag ciend; + char *cifmt; + ftnint cirec; +} cilist; + +/*internal read, write*/ +typedef struct +{ flag icierr; + char *iciunit; + flag iciend; + char *icifmt; + ftnint icirlen; + ftnint icirnum; +} icilist; + +/*open*/ +typedef struct +{ flag oerr; + ftnint ounit; + char *ofnm; + ftnlen ofnmlen; + char *osta; + char *oacc; + char *ofm; + ftnint orl; + char *oblnk; +} olist; + +/*close*/ +typedef struct +{ flag cerr; + ftnint cunit; + char *csta; +} cllist; + +/*rewind, backspace, endfile*/ +typedef struct +{ flag aerr; + ftnint aunit; +} alist; + +/* inquire */ +typedef struct +{ flag inerr; + ftnint inunit; + char *infile; + ftnlen infilen; + ftnint *inex; /*parameters in standard's order*/ + ftnint *inopen; + ftnint *innum; + ftnint *innamed; + char *inname; + ftnlen innamlen; + char *inacc; + ftnlen inacclen; + char *inseq; + ftnlen inseqlen; + char *indir; + ftnlen indirlen; + char *infmt; + ftnlen infmtlen; + char *inform; + ftnint informlen; + char *inunf; + ftnlen inunflen; + ftnint *inrecl; + ftnint *innrec; + char *inblank; + ftnlen inblanklen; +} inlist; + +#define VOID void + +union Multitype { /* for multiple entry points */ + integer1 g; + shortint h; + integer i; + /* longint j; */ + real r; + doublereal d; + complex c; + doublecomplex z; + }; + +typedef union Multitype Multitype; + +/*typedef long int Long;*/ /* No longer used; formerly in Namelist */ + +struct Vardesc { /* for Namelist */ + char *name; + char *addr; + ftnlen *dims; + int type; + }; +typedef struct Vardesc Vardesc; + +struct Namelist { + char *name; + Vardesc **vars; + int nvars; + }; +typedef struct Namelist Namelist; + +#define abs(x) ((x) >= 0 ? (x) : -(x)) +#define dabs(x) (doublereal)abs(x) +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#define dmin(a,b) (doublereal)min(a,b) +#define dmax(a,b) (doublereal)max(a,b) + +/* procedure parameter types for -A and -C++ */ + +#define F2C_proc_par_types 1 +#ifdef __cplusplus +typedef int /* Unknown procedure type */ (*U_fp)(...); +typedef shortint (*J_fp)(...); +typedef integer (*I_fp)(...); +typedef real (*R_fp)(...); +typedef doublereal (*D_fp)(...), (*E_fp)(...); +typedef /* Complex */ VOID (*C_fp)(...); +typedef /* Double Complex */ VOID (*Z_fp)(...); +typedef logical (*L_fp)(...); +typedef shortlogical (*K_fp)(...); +typedef /* Character */ VOID (*H_fp)(...); +typedef /* Subroutine */ int (*S_fp)(...); +#else +typedef int /* Unknown procedure type */ (*U_fp)(); +typedef shortint (*J_fp)(); +typedef integer (*I_fp)(); +typedef real (*R_fp)(); +typedef doublereal (*D_fp)(), (*E_fp)(); +typedef /* Complex */ VOID (*C_fp)(); +typedef /* Double Complex */ VOID (*Z_fp)(); +typedef logical (*L_fp)(); +typedef shortlogical (*K_fp)(); +typedef /* Character */ VOID (*H_fp)(); +typedef /* Subroutine */ int (*S_fp)(); +#endif +/* E_fp is for real functions when -R is not specified */ +typedef VOID C_f; /* complex function */ +typedef VOID H_f; /* character function */ +typedef VOID Z_f; /* double complex function */ +typedef doublereal E_f; /* real function with -R not specified */ + +/* undef any lower-case symbols that your C compiler predefines, e.g.: */ + +#ifndef Skip_f2c_Undefs +#undef cray +#undef gcos +#undef mc68010 +#undef mc68020 +#undef mips +#undef pdp11 +#undef sgi +#undef sparc +#undef sun +#undef sun2 +#undef sun3 +#undef sun4 +#undef u370 +#undef u3b +#undef u3b2 +#undef u3b5 +#undef unix +#undef vax +#endif +#endif diff --git a/src/matrix/camlapack/i_dnnt.c b/src/matrix/camlapack/i_dnnt.c new file mode 100644 index 0000000..332949c --- /dev/null +++ b/src/matrix/camlapack/i_dnnt.c @@ -0,0 +1,14 @@ +#include "f2c.h" + +#ifdef KR_headers +double floor(); +integer i_dnnt(x) doublereal *x; +#else +#undef abs +#include "math.h" +integer i_dnnt(doublereal *x) +#endif +{ +return( (*x)>=0 ? + floor(*x + .5) : -floor(.5 - *x) ); +} diff --git a/src/matrix/camlapack/idamax.c b/src/matrix/camlapack/idamax.c new file mode 100644 index 0000000..dc4ed06 --- /dev/null +++ b/src/matrix/camlapack/idamax.c @@ -0,0 +1,77 @@ +/* IDAMAX.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +integer idamax_(n, dx, incx) +integer *n; +doublereal *dx; +integer *incx; +{ + /* System generated locals */ + integer ret_val, i__1; + doublereal d__1; + + /* Local variables */ + static doublereal dmax__; + static integer i, ix; + + +/* finds the index of element having max. absolute value. */ +/* jack dongarra, linpack, 3/11/78. */ +/* modified 3/93 to return if incx .le. 0. */ + + + /* Parameter adjustments */ + --dx; + + /* Function Body */ + ret_val = 0; + if (*n < 1 || *incx <= 0) { + return ret_val; + } + ret_val = 1; + if (*n == 1) { + return ret_val; + } + if (*incx == 1) { + goto L20; + } + +/* code for increment not equal to 1 */ + + ix = 1; + dmax__ = abs(dx[1]); + ix += *incx; + i__1 = *n; + for (i = 2; i <= i__1; ++i) { + if ((d__1 = dx[ix], abs(d__1)) <= dmax__) { + goto L5; + } + ret_val = i; + dmax__ = (d__1 = dx[ix], abs(d__1)); +L5: + ix += *incx; +/* L10: */ + } + return ret_val; + +/* code for increment equal to 1 */ + +L20: + dmax__ = abs(dx[1]); + i__1 = *n; + for (i = 2; i <= i__1; ++i) { + if ((d__1 = dx[i], abs(d__1)) <= dmax__) { + goto L30; + } + ret_val = i; + dmax__ = (d__1 = dx[i], abs(d__1)); +L30: + ; + } + return ret_val; +} /* idamax_ */ + diff --git a/src/matrix/camlapack/ilaenv.c b/src/matrix/camlapack/ilaenv.c new file mode 100644 index 0000000..702e833 --- /dev/null +++ b/src/matrix/camlapack/ilaenv.c @@ -0,0 +1,572 @@ +/* ILAENV.F -- translated by f2c (version 19941215). + You must link the resulting object file with the libraries: + -lf2c -lm (in that order) +*/ + +#include "f2c.h" + +integer ilaenv_(ispec, name, opts, n1, n2, n3, n4, name_len, opts_len) +integer *ispec; +char *name, *opts; +integer *n1, *n2, *n3, *n4; +ftnlen name_len; +ftnlen opts_len; +{ + /* System generated locals */ + integer ret_val; + + /* Builtin functions */ + /* Subroutine */ int s_copy(); + integer s_cmp(); + + /* Local variables */ + static integer i; + static logical cname, sname; + static integer nbmin; + static char c1[1], c2[2], c3[3], c4[2]; + static integer ic, nb, iz, nx; + static char subnam[6]; + + +/* -- LAPACK auxiliary routine (preliminary version) -- */ +/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ +/* Courant Institute, Argonne National Lab, and Rice University */ +/* February 20, 1992 */ + +/* .. Scalar Arguments .. */ +/* .. */ + +/* Purpose */ +/* ======= */ + +/* ILAENV is called from the LAPACK routines to choose problem-dependent +*/ +/* parameters for the local environment. See ISPEC for a description of +*/ +/* the parameters. */ + +/* This version provides a set of parameters which should give good, */ +/* but not optimal, performance on many of the currently available */ +/* computers. Users are encouraged to modify this subroutine to set */ +/* the tuning parameters for their particular machine using the option */ +/* and problem size information in the arguments. */ + +/* This routine will not function correctly if it is converted to all */ +/* lower case. Converting it to all upper case is allowed. */ + +/* Arguments */ +/* ========= */ + +/* ISPEC (input) INTEGER */ +/* Specifies the parameter to be returned as the value of */ +/* ILAENV. */ +/* = 1: the optimal blocksize; if this value is 1, an unblocked +*/ +/* algorithm will give the best performance. */ +/* = 2: the minimum block size for which the block routine */ +/* should be used; if the usable block size is less than */ +/* this value, an unblocked routine should be used. */ +/* = 3: the crossover point (in a block routine, for N less */ +/* than this value, an unblocked routine should be used) */ +/* = 4: the number of shifts, used in the nonsymmetric */ +/* eigenvalue routines */ +/* = 5: the minimum column dimension for blocking to be used; */ +/* rectangular blocks must have dimension at least k by m, +*/ +/* where k is given by ILAENV(2,...) and m by ILAENV(5,...) +*/ +/* = 6: the crossover point for the SVD (when reducing an m by n +*/ +/* matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds +*/ +/* this value, a QR factorization is used first to reduce */ +/* the matrix to a triangular form.) */ +/* = 7: the number of processors */ +/* = 8: the crossover point for the multishift QR and QZ methods +*/ +/* for nonsymmetric eigenvalue problems. */ + +/* NAME (input) CHARACTER*(*) */ +/* The name of the calling subroutine, in either upper case or */ +/* lower case. */ + +/* OPTS (input) CHARACTER*(*) */ +/* The character options to the subroutine NAME, concatenated */ +/* into a single character string. For example, UPLO = 'U', */ +/* TRANS = 'T', and DIAG = 'N' for a triangular routine would */ +/* be specified as OPTS = 'UTN'. */ + +/* N1 (input) INTEGER */ +/* N2 (input) INTEGER */ +/* N3 (input) INTEGER */ +/* N4 (input) INTEGER */ +/* Problem dimensions for the subroutine NAME; these may not all +*/ +/* be required. */ + +/* (ILAENV) (output) INTEGER */ +/* >= 0: the value of the parameter specified by ISPEC */ +/* < 0: if ILAENV = -k, the k-th argument had an illegal value. +*/ + +/* Further Details */ +/* =============== */ + +/* The following conventions have been used when calling ILAENV from the +*/ +/* LAPACK routines: */ +/* 1) OPTS is a concatenation of all of the character options to */ +/* subroutine NAME, in the same order that they appear in the */ +/* argument list for NAME, even if they are not used in determining +*/ +/* the value of the parameter specified by ISPEC. */ +/* 2) The problem dimensions N1, N2, N3, N4 are specified in the order +*/ +/* that they appear in the argument list for NAME. N1 is used */ +/* first, N2 second, and so on, and unused problem dimensions are */ +/* passed a value of -1. */ +/* 3) The parameter value returned by ILAENV is checked for validity in +*/ +/* the calling subroutine. For example, ILAENV is used to retrieve +*/ +/* the optimal blocksize for STRTRI as follows: */ + +/* NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 ) */ +/* IF( NB.LE.1 ) NB = MAX( 1, N ) */ + +/* ===================================================================== +*/ + +/* .. Local Scalars .. */ +/* .. */ +/* .. Intrinsic Functions .. */ +/* .. */ +/* .. Executable Statements .. */ + + switch ((int)*ispec) { + case 1: goto L100; + case 2: goto L100; + case 3: goto L100; + case 4: goto L400; + case 5: goto L500; + case 6: goto L600; + case 7: goto L700; + case 8: goto L800; + } + +/* Invalid value for ISPEC */ + + ret_val = -1; + return ret_val; + +L100: + +/* Convert NAME to upper case if the first character is lower case. */ + + ret_val = 1; + s_copy(subnam, name, 6L, name_len); + ic = *(unsigned char *)subnam; + iz = 'Z'; + if (iz == 90 || iz == 122) { + +/* ASCII character set */ + + if (ic >= 97 && ic <= 122) { + *(unsigned char *)subnam = (char) (ic - 32); + for (i = 2; i <= 6; ++i) { + ic = *(unsigned char *)&subnam[i - 1]; + if (ic >= 97 && ic <= 122) { + *(unsigned char *)&subnam[i - 1] = (char) (ic - 32); + } +/* L10: */ + } + } + + } else if (iz == 233 || iz == 169) { + +/* EBCDIC character set */ + + if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= 162 && + ic <= 169) { + *(unsigned char *)subnam = (char) (ic + 64); + for (i = 2; i <= 6; ++i) { + ic = *(unsigned char *)&subnam[i - 1]; + if (ic >= 129 && ic <= 137 || ic >= 145 && ic <= 153 || ic >= + 162 && ic <= 169) { + *(unsigned char *)&subnam[i - 1] = (char) (ic + 64); + } +/* L20: */ + } + } + + } else if (iz == 218 || iz == 250) { + +/* Prime machines: ASCII+128 */ + + if (ic >= 225 && ic <= 250) { + *(unsigned char *)subnam = (char) (ic - 32); + for (i = 2; i <= 6; ++i) { + ic = *(unsigned char *)&subnam[i - 1]; + if (ic >= 225 && ic <= 250) { + *(unsigned char *)&subnam[i - 1] = (char) (ic - 32); + } +/* L30: */ + } + } + } + + *(unsigned char *)c1 = *(unsigned char *)subnam; + sname = *(unsigned char *)c1 == 'S' || *(unsigned char *)c1 == 'D'; + cname = *(unsigned char *)c1 == 'C' || *(unsigned char *)c1 == 'Z'; + if (! (cname || sname)) { + return ret_val; + } + s_copy(c2, subnam + 1, 2L, 2L); + s_copy(c3, subnam + 3, 3L, 3L); + s_copy(c4, c3 + 1, 2L, 2L); + + switch ((int)*ispec) { + case 1: goto L110; + case 2: goto L200; + case 3: goto L300; + } + +L110: + +/* ISPEC = 1: block size */ + +/* In these examples, separate code is provided for setting NB for */ +/* real and complex. We assume that NB will take the same value in */ +/* single or double precision. */ + + nb = 1; + + if (s_cmp(c2, "GE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } else if (s_cmp(c3, "QRF", 3L, 3L) == 0 || s_cmp(c3, "RQF", 3L, 3L) + == 0 || s_cmp(c3, "LQF", 3L, 3L) == 0 || s_cmp(c3, "QLF", 3L, + 3L) == 0) { + if (sname) { + nb = 32; + } else { + nb = 32; + } + } else if (s_cmp(c3, "HRD", 3L, 3L) == 0) { + if (sname) { + nb = 32; + } else { + nb = 32; + } + } else if (s_cmp(c3, "BRD", 3L, 3L) == 0) { + if (sname) { + nb = 32; + } else { + nb = 32; + } + } else if (s_cmp(c3, "TRI", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (s_cmp(c2, "PO", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (s_cmp(c2, "SY", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } else if (sname && s_cmp(c3, "TRD", 3L, 3L) == 0) { + nb = 1; + } else if (sname && s_cmp(c3, "GST", 3L, 3L) == 0) { + nb = 64; + } + } else if (cname && s_cmp(c2, "HE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + nb = 64; + } else if (s_cmp(c3, "TRD", 3L, 3L) == 0) { + nb = 1; + } else if (s_cmp(c3, "GST", 3L, 3L) == 0) { + nb = 64; + } + } else if (sname && s_cmp(c2, "OR", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } + } else if (cname && s_cmp(c2, "UN", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nb = 32; + } + } + } else if (s_cmp(c2, "GB", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + if (*n4 <= 64) { + nb = 1; + } else { + nb = 32; + } + } else { + if (*n4 <= 64) { + nb = 1; + } else { + nb = 32; + } + } + } + } else if (s_cmp(c2, "PB", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + if (*n2 <= 64) { + nb = 1; + } else { + nb = 32; + } + } else { + if (*n2 <= 64) { + nb = 1; + } else { + nb = 32; + } + } + } + } else if (s_cmp(c2, "TR", 2L, 2L) == 0) { + if (s_cmp(c3, "TRI", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (s_cmp(c2, "LA", 2L, 2L) == 0) { + if (s_cmp(c3, "UUM", 3L, 3L) == 0) { + if (sname) { + nb = 64; + } else { + nb = 64; + } + } + } else if (sname && s_cmp(c2, "ST", 2L, 2L) == 0) { + if (s_cmp(c3, "EBZ", 3L, 3L) == 0) { + nb = 1; + } + } + ret_val = nb; + return ret_val; + +L200: + +/* ISPEC = 2: minimum block size */ + + nbmin = 2; + if (s_cmp(c2, "GE", 2L, 2L) == 0) { + if (s_cmp(c3, "QRF", 3L, 3L) == 0 || s_cmp(c3, "RQF", 3L, 3L) == 0 || + s_cmp(c3, "LQF", 3L, 3L) == 0 || s_cmp(c3, "QLF", 3L, 3L) == + 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (s_cmp(c3, "HRD", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (s_cmp(c3, "BRD", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (s_cmp(c3, "TRI", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } + } else if (s_cmp(c2, "SY", 2L, 2L) == 0) { + if (s_cmp(c3, "TRF", 3L, 3L) == 0) { + if (sname) { + nbmin = 2; + } else { + nbmin = 2; + } + } else if (sname && s_cmp(c3, "TRD", 3L, 3L) == 0) { + nbmin = 2; + } + } else if (cname && s_cmp(c2, "HE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRD", 3L, 3L) == 0) { + nbmin = 2; + } + } else if (sname && s_cmp(c2, "OR", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } + } else if (cname && s_cmp(c2, "UN", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } else if (*(unsigned char *)c3 == 'M') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nbmin = 2; + } + } + } + ret_val = nbmin; + return ret_val; + +L300: + +/* ISPEC = 3: crossover point */ + + nx = 0; + if (s_cmp(c2, "GE", 2L, 2L) == 0) { + if (s_cmp(c3, "QRF", 3L, 3L) == 0 || s_cmp(c3, "RQF", 3L, 3L) == 0 || + s_cmp(c3, "LQF", 3L, 3L) == 0 || s_cmp(c3, "QLF", 3L, 3L) == + 0) { + if (sname) { + nx = 128; + } else { + nx = 128; + } + } else if (s_cmp(c3, "HRD", 3L, 3L) == 0) { + if (sname) { + nx = 128; + } else { + nx = 128; + } + } else if (s_cmp(c3, "BRD", 3L, 3L) == 0) { + if (sname) { + nx = 128; + } else { + nx = 128; + } + } + } else if (s_cmp(c2, "SY", 2L, 2L) == 0) { + if (sname && s_cmp(c3, "TRD", 3L, 3L) == 0) { + nx = 1; + } + } else if (cname && s_cmp(c2, "HE", 2L, 2L) == 0) { + if (s_cmp(c3, "TRD", 3L, 3L) == 0) { + nx = 1; + } + } else if (sname && s_cmp(c2, "OR", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nx = 128; + } + } + } else if (cname && s_cmp(c2, "UN", 2L, 2L) == 0) { + if (*(unsigned char *)c3 == 'G') { + if (s_cmp(c4, "QR", 2L, 2L) == 0 || s_cmp(c4, "RQ", 2L, 2L) == 0 + || s_cmp(c4, "LQ", 2L, 2L) == 0 || s_cmp(c4, "QL", 2L, 2L) + == 0 || s_cmp(c4, "HR", 2L, 2L) == 0 || s_cmp(c4, "TR", + 2L, 2L) == 0 || s_cmp(c4, "BR", 2L, 2L) == 0) { + nx = 128; + } + } + } + ret_val = nx; + return ret_val; + +L400: + +/* ISPEC = 4: number of shifts (used by xHSEQR) */ + + ret_val = 6; + return ret_val; + +L500: + +/* ISPEC = 5: minimum column dimension (not used) */ + + ret_val = 2; + return ret_val; + +L600: + +/* ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) */ + + ret_val = (integer) ((real) min(*n1,*n2) * (float)1.6); + return ret_val; + +L700: + +/* ISPEC = 7: number of processors (not used) */ + + ret_val = 1; + return ret_val; + +L800: + +/* ISPEC = 8: crossover point for multishift (used by xHSEQR) */ + + ret_val = 50; + return ret_val; + +/* End of ILAENV */ + +} /* ilaenv_ */ + diff --git a/src/matrix/camlapack/pow_di.c b/src/matrix/camlapack/pow_di.c new file mode 100644 index 0000000..6f0e85e --- /dev/null +++ b/src/matrix/camlapack/pow_di.c @@ -0,0 +1,34 @@ +#include "f2c.h" + +#ifdef KR_headers +double pow_di(ap, bp) doublereal *ap; integer *bp; +#else +double pow_di(doublereal *ap, integer *bp) +#endif +{ +double pow, x; +integer n; + +pow = 1; +x = *ap; +n = *bp; + +if(n != 0) + { + if(n < 0) + { + n = -n; + x = 1/x; + } + for( ; ; ) + { + if(n & 01) + pow *= x; + if(n >>= 1) + x *= x; + else + break; + } + } +return(pow); +} diff --git a/src/matrix/camlapack/s_cmp.c b/src/matrix/camlapack/s_cmp.c new file mode 100644 index 0000000..b891a6c --- /dev/null +++ b/src/matrix/camlapack/s_cmp.c @@ -0,0 +1,44 @@ +#include "f2c.h" + +/* compare two strings */ + +#ifdef KR_headers +integer s_cmp(a0, b0, la, lb) char *a0, *b0; ftnlen la, lb; +#else +integer s_cmp(char *a0, char *b0, ftnlen la, ftnlen lb) +#endif +{ +register unsigned char *a, *aend, *b, *bend; +a = (unsigned char *)a0; +b = (unsigned char *)b0; +aend = a + la; +bend = b + lb; + +if(la <= lb) + { + while(a < aend) + if(*a != *b) + return( *a - *b ); + else + { ++a; ++b; } + + while(b < bend) + if(*b != ' ') + return( ' ' - *b ); + else ++b; + } + +else + { + while(b < bend) + if(*a == *b) + { ++a; ++b; } + else + return( *a - *b ); + while(a < aend) + if(*a != ' ') + return(*a - ' '); + else ++a; + } +return(0); +} diff --git a/src/matrix/camlapack/s_copy.c b/src/matrix/camlapack/s_copy.c new file mode 100644 index 0000000..13f40a5 --- /dev/null +++ b/src/matrix/camlapack/s_copy.c @@ -0,0 +1,27 @@ +#include "f2c.h" + +/* assign strings: a = b */ + +#ifdef KR_headers +VOID s_copy(a, b, la, lb) register char *a, *b; ftnlen la, lb; +#else +void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb) +#endif +{ +register char *aend, *bend; + +aend = a + la; + +if(la <= lb) + while(a < aend) + *a++ = *b++; + +else + { + bend = b + lb; + while(b < bend) + *a++ = *b++; + while(a < aend) + *a++ = ' '; + } +} diff --git a/src/matrix/cammva.h b/src/matrix/cammva.h new file mode 100755 index 0000000..50e70a6 --- /dev/null +++ b/src/matrix/cammva.h @@ -0,0 +1,5 @@ +#include "dmatrix.h" +#include "dvector.h" +#include "darray.h" + + diff --git a/src/matrix/camtype.h b/src/matrix/camtype.h new file mode 100755 index 0000000..0cbdfde --- /dev/null +++ b/src/matrix/camtype.h @@ -0,0 +1,72 @@ +// +//****************************************************************************** +// CAMTYPE.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Fri Sep 22 12:31:07 1995 +// +//******************************************************************************** +// + +#ifndef __CAMTYPE__ +#define __CAMTYPE__ +// +#include "mvaimpexp.h" + +class __IMPEXP__ CAMType +{ + +protected : + + int Value; + +public : + + + enum {typeNull ,typeInt ,typeLong ,typeFloat ,typeDouble ,typeComplex }; +// +// constructors +// + CAMType() {Value = 0;}; + CAMType(const CAMType& T) {Value = T.Value; }; + CAMType(int dataTypeValue) {Value = dataTypeValue;}; + ~CAMType(){}; +// +// Assignment +// + void operator=(CAMType & T){Value = T.Value;}; +// +// Access Functions +// + int getTypeValue() {return Value;}; + void setTypeValue(int dataTypeValue) {Value = dataTypeValue;}; + int getConversionValue() + { + int r; + switch (Value) + { + case CAMType::typeInt : r = 10; break; + case CAMType::typeLong : r = 20; break; + case CAMType::typeFloat : r = 20; break; + case CAMType::typeDouble : r = 30; break; + case CAMType::typeComplex : r = 40; break; + } + return r; + }; + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + diff --git a/src/matrix/darray.cpp b/src/matrix/darray.cpp new file mode 100755 index 0000000..0519ecb --- /dev/null +++ b/src/matrix/darray.cpp @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/matrix/darray.h b/src/matrix/darray.h new file mode 100755 index 0000000..af9c397 --- /dev/null +++ b/src/matrix/darray.h @@ -0,0 +1,523 @@ +// +//****************************************************************************** +// DARRAY.H +//****************************************************************************** +// + +#include "strctbse.h" +#include "datahndl.h" +#include "arraybse.h" +#include "range.h" +#include "camtype.h" +#include "under.h" + +// +// +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Thu Nov 02 13:42:45 1995 +// +//******************************************************************************** +// + +#ifndef _CAMDOUBLEARRAY_ +#define _CAMDOUBLEARRAY_ + +#include "mvaimpexp.h" + +class __IMPEXP__ CAMdoubleArray : public CAMarrayBase +{ + +public : + +// +// Constructors +// + CAMdoubleArray():CAMarrayBase(CAMType::typeDouble){}; + CAMdoubleArray(const CAMdoubleArray& A):CAMarrayBase(*((CAMarrayBase*)&A)){}; + CAMdoubleArray(const CAMarrayBase& A):CAMarrayBase(A){}; + CAMdoubleArray(long n):CAMarrayBase(CAMType::typeDouble, n){}; + CAMdoubleArray(const CAMrange& R1, const CAMrange& R2 = CAMnullRange, + const CAMrange& R3 = CAMnullRange, const CAMrange&R4 = CAMnullRange, + const CAMrange& R5 = CAMnullRange, const CAMrange&R6 = CAMnullRange, + const CAMrange& R7 = CAMnullRange) : + CAMarrayBase(CAMType::typeDouble,R1, R2, R3, R4, R5, R6, R7){ }; +// +// Assignment +// + void operator = (const CAMdoubleArray& A) + {CAMarrayBase* basePtr = this; const CAMarrayBase* AbasePtr = + (CAMarrayBase*)&A; basePtr->operator=(*AbasePtr);}; + void operator =( const CAMarrayBase& A) + {CAMarrayBase* basePtr = this; basePtr->operator=(A);}; + void operator = (double value) + {CAMarrayBase* basePtr = this; basePtr->operator=(value);}; +// +// initialization +// + void initialize() + {CAMarrayBase* basePtr = this; basePtr->initialize(CAMType::typeDouble);}; + void initialize(const CAMdoubleArray& A) + {CAMarrayBase* basePtr = this; basePtr->initialize(A);}; + void initialize(const CAMarrayBase& A) + {CAMarrayBase* basePtr = this; basePtr->initialize(A);}; + void initialize(long n) + {CAMarrayBase* basePtr = this; basePtr->initialize(CAMType::typeDouble, n);}; + void initialize(const CAMrange& R1, const CAMrange& R2 = CAMnullRange, + const CAMrange& R3 = CAMnullRange, const CAMrange&R4 = CAMnullRange, + const CAMrange& R5 = CAMnullRange, const CAMrange&R6 = CAMnullRange, + const CAMrange& R7 = CAMnullRange){CAMarrayBase* basePtr = this; + basePtr->initialize(CAMType::typeDouble,R1, R2, R3, R4, R5, R6, R7);}; +// +// Access Functions +// + inline double& operator()(long i1) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)); + return *(dataPtr + offset); +}; + inline double& operator()(long i1, long i2) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + + long offset = + (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)*(i2 - *(beginPtr +1)); + + return (*(dataPtr + offset)); +}; + inline double& operator()(long i1, long i2, long i3) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + (i3 - *(beginPtr + 2))); + return (*(dataPtr + offset)); +}; + inline double& operator()(long i1, long i2, long i3, long i4) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ( (i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ( (i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)*(i4 - *(beginPtr + 3)))); + return (*(dataPtr + offset)); +}; + inline double& operator()(long i1, long i2, long i3, long i4, long i5) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4,i5); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ((i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)* + ((i4 - *(beginPtr + 3)) + + ((*(endPtr +3) - *(beginPtr +3)) + 1)*(i5 - *(beginPtr + 4))))); + return (*(dataPtr + offset)); +}; + inline double& operator()(long i1, long i2, long i3, long i4, long i5, long i6) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4,i5,i6); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ((i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)* + ((i4 - *(beginPtr + 3)) + + ((*(endPtr +3) - *(beginPtr +3)) + 1)* + ((i5 - *(beginPtr + 4)) + + ((*(endPtr +4) - *(beginPtr +4)) + 1)*(i6 - *(beginPtr + 5)))))); + return (*(dataPtr + offset)); +}; + inline double& operator()(long i1, long i2, long i3, long i4, long i5, long i6, long i7) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4,i5,i6,i7); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ((i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)* + ((i4 - *(beginPtr + 3)) + + ((*(endPtr +3) - *(beginPtr +3)) + 1)* + ((i5 - *(beginPtr + 4)) + + ((*(endPtr +4) - *(beginPtr +4)) + 1)* + ((i6 - *(beginPtr + 5)) + + ((*(endPtr +5) - *(beginPtr +5)) + 1)*(i7 - *(beginPtr + 6))))))); + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)); + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1, long i2) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + + long offset = + (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)*(i2 - *(beginPtr +1)); + + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1, long i2, long i3) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + (i3 - *(beginPtr + 2))); + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1, long i2, long i3, long i4) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ( (i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ( (i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)*(i4 - *(beginPtr + 3)))); + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1, long i2, long i3, long i4, long i5) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4,i5); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ((i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)* + ((i4 - *(beginPtr + 3)) + + ((*(endPtr +3) - *(beginPtr +3)) + 1)*(i5 - *(beginPtr + 4))))); + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1, long i2, long i3, long i4, long i5, long i6) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4,i5,i6); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ((i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)* + ((i4 - *(beginPtr + 3)) + + ((*(endPtr +3) - *(beginPtr +3)) + 1)* + ((i5 - *(beginPtr + 4)) + + ((*(endPtr +4) - *(beginPtr +4)) + 1)*(i6 - *(beginPtr + 5)))))); + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1, long i2, long i3, long i4, long i5, long i6, long i7) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMarrayBase::indexCheck(Structure,i1,i2,i3,i4,i5,i6,i7); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)* + ((i2 - *(beginPtr +1)) + + ((*(endPtr +1) - *(beginPtr +1)) + 1)* + ((i3 - *(beginPtr + 2)) + + ((*(endPtr +2) - *(beginPtr +2)) + 1)* + ((i4 - *(beginPtr + 3)) + + ((*(endPtr +3) - *(beginPtr +3)) + 1)* + ((i5 - *(beginPtr + 4)) + + ((*(endPtr +4) - *(beginPtr +4)) + 1)* + ((i6 - *(beginPtr + 5)) + + ((*(endPtr +5) - *(beginPtr +5)) + 1)*(i7 - *(beginPtr + 6))))))); + return (*(dataPtr + offset)); +}; + CAMdoubleArray operator() (const CAMrange& R1) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + const CAMdoubleArray operator()(const CAMrange& R1) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + const CAMdoubleArray operator()(const CAMrange& R1, const CAMrange& R2) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + CAMdoubleArray operator() (const CAMrange& R1, const CAMrange& R2) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + const CAMdoubleArray operator()(const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2,R3); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + CAMdoubleArray operator() (const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2, R3); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + const CAMdoubleArray operator()(const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2,R3,R4); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + CAMdoubleArray operator() (const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2, R3, R4); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + const CAMdoubleArray operator()(const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4, const CAMrange& R5) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2,R3,R4, R5); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + CAMdoubleArray operator() (const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4, const CAMrange& R5) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2, R3, R4, R5); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + CAMdoubleArray operator() (const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4, const CAMrange& R5, +const CAMrange& R6) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2, R3, R4, R5, R6); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + const CAMdoubleArray operator()(const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4, const CAMrange& R5, const CAMrange& R6) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2,R3,R4, R5, R6); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + CAMdoubleArray operator() (const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4, const CAMrange& R5, +const CAMrange& R6, const CAMrange& R7) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2, R3, R4, R5, R6, R7); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + const CAMdoubleArray operator()(const CAMrange& R1, const CAMrange& R2, +const CAMrange& R3, const CAMrange& R4, const CAMrange& R5, const CAMrange& R6, +const CAMrange& R7) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2,R3,R4, R5, R6, R7); + CAMdoubleArray A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; +// +// data pointer access +// + double* getDataPointer() const {return (double*)DataP->getDataPointer();}; + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + + + + + diff --git a/src/matrix/datahndl.cpp b/src/matrix/datahndl.cpp new file mode 100755 index 0000000..0ca064b --- /dev/null +++ b/src/matrix/datahndl.cpp @@ -0,0 +1,478 @@ +#include "datahndl.h" +#include "blas.h" +#include "mvaexit.h" + + +// +//****************************************************************************** +// DATAHNDL.CPP +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Thu Sep 07 00:49:17 1995 +// +//******************************************************************************** +// +// +//******************************************************************************** +// CONSTRUCTORS +//******************************************************************************** + +CAMdataHandler::CAMdataHandler() +{ + dataType = 0; + dataPointer = 0; + dataSize = 0; + temporaryFlag = 0; + referenceCount = 0; +} + +CAMdataHandler::CAMdataHandler( const CAMdataHandler& A) +{ + if(A.temporaryFlag == 1) + { + dataType = A.dataType; + dataSize = A.dataSize; + dataPointer = A.dataPointer; + temporaryFlag = 0; + referenceCount = 0; + + } + else + { + allocateData(A.dataSize,A.dataType); + setTypeFlag(A.dataType); + copyData(A.dataSize,A.dataPointer); + temporaryFlag = 0; + referenceCount = 0; + } +} + +CAMdataHandler::CAMdataHandler(long size, int dType) +{ + allocateData(size,dType); + setTypeFlag(dType); + temporaryFlag = 0; + referenceCount = 0; +} +// +//******************************************************************************** +// DESTRUCTOR +//******************************************************************************** +// +CAMdataHandler::~CAMdataHandler() +{ + if(temporaryFlag == 0) destroyData(); +} +// +//******************************************************************************** +// OUTPUT +//******************************************************************************** +// +ostream& operator <<(ostream& out_stream, const CAMdataHandler& A) +{ + +#ifndef __NO_COMPLEX__ + complex* cdataP; +#endif + + long i; + + switch(A.dataType) + { + case CAMType::typeInt : + int i_out; + for(i = 0; i < A.dataSize; i++) + {A.getDataValue(i, i_out); out_stream << i_out << " ";} + out_stream << endl; + break; + + case CAMType::typeLong : + long l_out; + for(i = 0; i < A.dataSize; i++) + {A.getDataValue(i, l_out); out_stream << l_out << " ";} + out_stream << endl; + break; + + case CAMType::typeFloat : + float f_out; + for(i = 0; i < A.dataSize; i++) + {A.getDataValue(i, f_out); out_stream << f_out << " ";} + out_stream << endl; + break; + + case CAMType::typeDouble : + double d_out; + for(i = 0; i < A.dataSize; i++) + {A.getDataValue(i, d_out); out_stream << d_out << " ";} + out_stream << endl; + break; + +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + cdataP = (complex*)A.dataPointer; + for(i = 0; i < A.dataSize; i++) + out_stream << *(cdataP + i) << " "; + out_stream << endl; + break; +#endif + + } + return(out_stream); + +} +// +//******************************************************************************** +// ASSIGNMENT +//******************************************************************************** +// +CAMdataHandler& CAMdataHandler::operator =( const CAMdataHandler& A) +{ + if(A.temporaryFlag == 1) + { + dataType = A.dataType; + dataSize = A.dataSize; + dataPointer = A.dataPointer; + temporaryFlag = 0; + referenceCount = 0; + } + else + { + destroyData(); + allocateData(A.dataSize,A.dataType); + setTypeFlag(A.dataType); + copyData(A.dataSize,A.dataPointer); + temporaryFlag = 0; + referenceCount = 0; + } + return *this; +} + +// +//******************************************************************************** +// MEMBER_FUNCTIONS +//******************************************************************************** +// + +void CAMdataHandler::initialize() +{ + destroyData(); + + dataType = 0; + dataPointer = 0; + dataSize = 0; + temporaryFlag = 0; + referenceCount = 0; +} + +void CAMdataHandler::initialize(const CAMdataHandler& A) +{ + + + if(A.temporaryFlag == 1) + { + dataType = A.dataType; + dataSize = A.dataSize; + dataPointer = A.dataPointer; + temporaryFlag = 0; + } + else + { + destroyData(); + allocateData(A.dataSize,A.dataType); + setTypeFlag(A.dataType); + copyData(A.dataSize,A.dataPointer); + temporaryFlag = 0; + } +} + +void CAMdataHandler::initialize(long size, int dType) +{ + destroyData(); + allocateData(size,dType); + setTypeFlag(dType); + temporaryFlag = 0; +} +void CAMdataHandler::setTypeFlag(int dType) +{ + + switch(dType) + { + case CAMType::typeInt : + + dataType = CAMType::typeInt; + break; + + case CAMType::typeLong : + + dataType = CAMType::typeLong; + break; + + case CAMType::typeFloat : + + dataType = CAMType::typeFloat; + break; + + case CAMType::typeDouble : + + dataType = CAMType::typeDouble; + break; + +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + dataType = CAMType::typeComplex; + break; +#endif + } + +} + +void CAMdataHandler::allocateData(long size, int dType) +{ + + switch(dType) + { + case CAMType::typeInt : + dataSize = size; + dataPointer = new int[size]; + break; + + case CAMType::typeLong : + dataSize = size; + dataPointer = new long[size]; + break; + + case CAMType::typeFloat : + dataSize = size; + dataPointer = new float[size]; + break; + + case CAMType::typeDouble : + dataSize = size; + dataPointer = new double[size]; + break; + +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + dataSize = size; + dataPointer = new complex[size]; + break; +#endif + } +// +// initialize with zero's +// +#ifndef __NO_BLAS__ + int izero = 0; + long lzero = 0; + float fzero = 0.0; + double dzero = 0.0; + long strideX = 0; + long strideY = 1; +#endif + + switch(dType) + { + case CAMType::typeInt : + register int* idataP; +#ifdef __NO_BLAS__ + for(idataP = (int*)dataPointer; idataP < (int*)dataPointer + size; idataP++) + *(idataP) = 0; +#else + idataP = (int*)dataPointer; + icopy_(&size,&izero,&strideX, idataP, &strideY); +#endif + break; + + case CAMType::typeLong : + register long* ldataP; +#ifdef __NO_BLAS__ + for(ldataP = (long*)dataPointer; ldataP < (long*)dataPointer + size; ldataP++) + *(ldataP) = 0; +#else + ldataP = (long*)dataPointer; + lcopy_(&size,&lzero,&strideX, ldataP, &strideY); +#endif + break; + + case CAMType::typeFloat : + register float* fdataP; +#ifdef __NO_BLAS__ + for(fdataP = (float*)dataPointer; fdataP < (float*)dataPointer + size; fdataP++) + *(fdataP) = 0.0; +#else + fdataP = (float*)dataPointer; + scopy_(&size,&fzero,&strideX, fdataP, &strideY); +#endif + break; + + case CAMType::typeDouble : + register double* ddataP; +#ifdef __NO_BLAS__ + for(ddataP = (double*)dataPointer; ddataP < (double*)dataPointer + size; ddataP++) + *(ddataP) = 0.0; +#else + ddataP = (double*)dataPointer; + dcopy_(&size,&dzero,&strideX, ddataP, &strideY); +#endif + + break; + +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + complex* cdataP; + for(cdataP = (complex*)dataPointer; cdataP < (complex*)dataPointer + size; cdataP++) + *(cdataP) = complex(0.0,0.0); + break; +#endif + + } +} + +void CAMdataHandler::copyData(long Size, void* dataP) +{ +#ifndef __NO_BLAS__ + long strideX = 1; + long strideY = 1; +#endif + + switch(dataType) + { + case CAMType::typeInt : + register int* idataP; register int* inIdataP; +#ifdef __NO_BLAS__ + for(idataP = (int*)dataPointer, inIdataP = (int*)dataP; + idataP < (int*)dataPointer + Size; idataP++, inIdataP++) + *(idataP) = *(inIdataP); +#else + idataP = (int*)dataPointer; + inIdataP = (int*)dataP; + icopy_(&Size,inIdataP,&strideX, idataP, &strideY); +#endif + + break; + + case CAMType::typeLong : + register long* ldataP; register long* inLdataP; +#ifdef __NO_BLAS__ + for(ldataP = (long*)dataPointer, inLdataP = (long*)dataP; + ldataP < (long*)dataPointer + Size; ldataP++, inLdataP++) + *(ldataP) = *(inLdataP); +#else + ldataP = (long*)dataPointer; + inLdataP = (long*)dataP; + lcopy_(&Size,inLdataP,&strideX, ldataP, &strideY); +#endif + + break; + + case CAMType::typeFloat : + register float* fdataP; register float* inFdataP; +#ifdef __NO_BLAS__ + for(fdataP = (float*)dataPointer, inFdataP = (float*)dataP; + fdataP < (float*)dataPointer + Size; fdataP++, inFdataP++) + *(fdataP) = *(inFdataP); +#else + fdataP = (float*)dataPointer; + inFdataP = (float*)dataP; + scopy_(&Size,inFdataP,&strideX, fdataP, &strideY); +#endif + + break; + + case CAMType::typeDouble : + register double* ddataP; register double* inDdataP; +#ifdef __NO_BLAS__ + for(ddataP = (double*)dataPointer, inDdataP = (double*)dataP; + ddataP < (double*)dataPointer + Size; ddataP++, inDdataP++) + *(ddataP) = *(inDdataP); +#else + ddataP = (double*)dataPointer; + inDdataP = (double*)dataP; + dcopy_(&Size,inDdataP,&strideX, ddataP, &strideY); +#endif + + break; + +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + complex* cdataP; complex* inCdataP; + for(cdataP = (complex*)dataPointer, inCdataP = (complex*)dataP; + cdataP < (complex*)dataPointer + Size; cdataP++, inCdataP++) + *(cdataP) = *(inCdataP); + break; +#endif + + } +} + +void CAMdataHandler::destroyData() +{ + if(dataType != 0) + { + switch(dataType) + { + case CAMType::typeInt : + int* idataP; + idataP = (int*)dataPointer; + if(idataP != 0) delete [] idataP; + break; + + case CAMType::typeLong : + long* ldataP; + ldataP = (long*)dataPointer; + if(ldataP != 0) delete [] ldataP; + break; + + case CAMType::typeFloat : + float* fdataP; + fdataP = (float*)dataPointer; + if(fdataP != 0) delete [] fdataP; + break; + + case CAMType::typeDouble : + double* ddataP; + ddataP = (double*)dataPointer; + if(ddataP != 0) delete [] ddataP; + break; + +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + complex* cdataP; + cdataP = (complex*)dataPointer; + if(cdataP != 0) delete [] cdataP; + break; +#endif + } + + } +} +// +//******************************************************************************** +// Reference Counting Functions +//******************************************************************************** +// + +void CAMdataHandler::incrementReferenceCount() +{ + if(referenceCount == 0) CAMdataHandler::referenceCountError(); + referenceCount++; +} + +void CAMdataHandler::referenceCountError() +{ +cerr << " Cannot Use Reference Counting on Objects New\'d by the Compiler " << endl; +CAMmvaExit(); +} +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + + + diff --git a/src/matrix/datahndl.h b/src/matrix/datahndl.h new file mode 100755 index 0000000..664e88f --- /dev/null +++ b/src/matrix/datahndl.h @@ -0,0 +1,109 @@ +// +//****************************************************************************** +// DATAHNDL.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Mon Mar 11 12:55:09 1996 +// +//******************************************************************************** +// + +#include +#include "camtype.h" + +#ifndef __NO_COMPLEX__ +#define __NO_COMPLEX__ +#endif +#ifndef __NO_COMPLEX__ +#include +#endif + +#ifndef __CAMDATAHANDLER__ +#define __CAMDATAHANDLER__ + +#include "mvaimpexp.h" // B + +class __IMPEXP__ CAMdataHandler +{ + +public : + + int dataType; + void* dataPointer; + long dataSize; + int temporaryFlag; + int referenceCount; + +public : + +// +// Constructors +// + CAMdataHandler(); + CAMdataHandler( const CAMdataHandler& A); + CAMdataHandler(long size, int dType); +// +// Destructor +// + ~CAMdataHandler(); +// +// Assignment +// + CAMdataHandler& operator = ( const CAMdataHandler& A); +// +// Output +// + __IMPEXP__ friend ostream& operator <<(ostream& out_stream, const CAMdataHandler& A); +// +// +// + void initialize(); + void initialize(const CAMdataHandler& H); + void initialize(long size, int dType); + void allocateData(long size, int dType); + void copyData(long size, void* dataP); + void destroyData(); + void setTypeFlag(int dType); + int getDataType() const {return dataType;}; + long getDataSize() const {return dataSize;}; + void setDataSize(long size){dataSize = size;}; + void setTemporaryFlag(){temporaryFlag = 1;}; + int getTemporaryFlag()const{return temporaryFlag;}; + void incrementReferenceCount(); + void decrementReferenceCount(){referenceCount--;}; + int getReferenceCount() const {return referenceCount;}; + void setReferenceCount(int refValue){referenceCount = refValue;}; + static void referenceCountError(); +// +// Data Pointer Access +// + void* getDataPointer() const {return dataPointer;}; + void setDataPointer(int* i){dataPointer = i;}; + void setDataPointer(long* l){dataPointer = l;}; + void setDataPointer(float* f){dataPointer = f;}; + void setDataPointer(double* d){dataPointer = d;}; + void getDataValue(long index, int& i) const {i = *((int*)(dataPointer) + index);}; + void getDataValue(long index, long& l) const {l = *((long*)(dataPointer) + index);}; + void getDataValue(long index, float& f) const {f = *((float*)(dataPointer) + index);}; + void getDataValue(long index, double& d) const {d = *((double*)(dataPointer) + index);}; +#ifndef __NO_COMPLEX__ + void setDataPointer(complex* c){dataPointer = c;}; + void getDataValue(long index, complex& c) const {c = *((complex*)(dataPointer) + index);} +#endif + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + diff --git a/src/matrix/dbengnea.cpp b/src/matrix/dbengnea.cpp new file mode 100755 index 0000000..3964ee5 --- /dev/null +++ b/src/matrix/dbengnea.cpp @@ -0,0 +1,1124 @@ +#include "bnengine.h" +#include "strctbse.h" +#include "datahndl.h" +#include "blas.h" + +void CAMbinaryEngine::doubleAequalToB(CAMstructureBase &Astructure, CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata) +{ + double* AdataP = (double*)Adata.getDataPointer(); + double* BdataP = (double*)Bdata.getDataPointer(); + + CAMdataHandler Btemporary; + if(AdataP == BdataP) + { + Btemporary.initialize(Bdata); + BdataP = (double*)Btemporary.getDataPointer(); + } + +#ifndef __NO_BLAS__ + long strideA; + long strideB; + long Size; +#endif + + if((Astructure.isSubset() == 0)&&(Bstructure.isSubset() == 0)) + { +#ifdef __NO_BLAS__ + register double* aptr; register double* bptr; + for(aptr = AdataP, bptr = BdataP; + aptr < AdataP + Adata.getDataSize(); + aptr++, bptr++) { *aptr = *bptr; }; +#else + strideA = 1; + strideB = 1; + Size = Adata.getDataSize(); + + dcopy_(&Size,BdataP,&strideB, AdataP, &strideA); +#endif + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + long BloopDimension; + long BOffset; + MVAlongBase BCount; + MVAlongBase BStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + Bstructure.getNormalizedLoops(BloopDimension,BOffset, BCount, BStride); + + register long i1, i2, i3, i4, i5, i6, i7; + register long j1, j2, j3, j4, j5, j6, j7; + + double* AOffptr = AdataP + AOffset; + double* BOffptr = BdataP + BOffset; + + register double* Ap1; register double* Bp1; + register double* Ap2; register double* Bp2; + register double* Ap3; register double* Bp3; + register double* Ap4; register double* Bp4; + register double* Ap5; register double* Bp5; + register double* Ap6; register double* Bp6; + +#ifndef __NO_BLAS__ + strideA = AStride[0]; + strideB = BStride[0]; + Size = ACount[0]; +#endif + + switch(AloopDimension) + { + case 1 : +#ifdef __NO_BLAS__ + for(i1=0, j1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(AOffptr + i1) = *(BOffptr + j1); + }; +#else + Bp1 = BOffptr; + Ap1 = AOffptr; + dcopy_(&Size,Bp1,&strideB, Ap1, &strideA); +#endif + + break; + + case 2 : + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = AOffptr + i2; Bp1 = BOffptr + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1)= *(Bp1 + j1); + } +#else + dcopy_(&Size,Bp1,&strideB, Ap1, &strideA); +#endif + }; + break; + + case 3 : + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = AOffptr + i3; Bp2 = BOffptr + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = *(Bp1 + j1); + } +#else + dcopy_(&Size,Bp1,&strideB, Ap1, &strideA); +#endif + }}; + break; + + case 4 : + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = AOffptr + i4; Bp3 = BOffptr + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = *(Bp1 + j1); + } +#else + dcopy_(&Size,Bp1,&strideB, Ap1, &strideA); +#endif + }}}; + break; + + case 5 : + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = AOffptr + i5; Bp4 = BOffptr + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = *(Bp1 + j1); + } +#else + dcopy_(&Size,Bp1,&strideB, Ap1, &strideA); +#endif + }}}}; + break; + + case 6 : + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = AOffptr+ i6; Bp5 = BOffptr + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = *(Bp1 + j1); + } +#else + dcopy_(&Size,Bp1,&strideB, Ap1, &strideA); +#endif + }}}}}; + break; + + case 7 : + for(i7=0, j7 = 0; i7 < ACount[6]*AStride[6]; i7+=AStride[6], j7+=BStride[6]) + { Ap6 = AOffptr + i7; Bp6 = BOffptr + j7; + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = Ap6 + i6; Bp5 = Bp6 + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = *(Bp1 + j1); + } +#else + dcopy_(&Size,Bp1,&strideB, Ap1, &strideA); +#endif + }}}}}}; + break; + + } +} + +} + +void CAMbinaryEngine::doubleAequalToMinusB(CAMstructureBase &Astructure, CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata) +{ + double* AdataP = (double*)Adata.getDataPointer(); + double* BdataP = (double*)Bdata.getDataPointer(); + + CAMdataHandler Btemporary; + if(AdataP == BdataP) + { + Btemporary.initialize(Bdata); + BdataP = (double*)Btemporary.getDataPointer(); + } + + if((Astructure.isSubset() == 0)&&(Bstructure.isSubset() == 0)) + { + register double* aptr; register double* bptr; + for(aptr = AdataP, bptr = BdataP; + aptr < AdataP + Adata.getDataSize(); + aptr++, bptr++) { *aptr = -(*bptr);}; + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + long BloopDimension; + long BOffset; + MVAlongBase BCount; + MVAlongBase BStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + Bstructure.getNormalizedLoops(BloopDimension,BOffset, BCount, BStride); + + register long i1, i2, i3, i4, i5, i6, i7; + register long j1, j2, j3, j4, j5, j6, j7; + + double* AOffptr = AdataP + AOffset; + double* BOffptr = BdataP + BOffset; + + register double* Ap1; register double* Bp1; + register double* Ap2; register double* Bp2; + register double* Ap3; register double* Bp3; + register double* Ap4; register double* Bp4; + register double* Ap5; register double* Bp5; + register double* Ap6; register double* Bp6; + + + switch(AloopDimension) + { + case 1 : + for(i1=0, j1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(AOffptr + i1) = -(*(BOffptr + j1)); + }; + + break; + + case 2 : + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = AOffptr + i2; Bp1 = BOffptr + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1)= -(*(Bp1 + j1)); + }}; + break; + + case 3 : + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = AOffptr + i3; Bp2 = BOffptr + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = -(*(Bp1 + j1)); + }}}; + break; + + case 4 : + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = AOffptr + i4; Bp3 = BOffptr + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) =-(*(Bp1 + j1)); + }}}}; + break; + + case 5 : + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = AOffptr + i5; Bp4 = BOffptr + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = -(*(Bp1 + j1)); + }}}}}; + break; + + case 6 : + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = AOffptr+ i6; Bp5 = BOffptr + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) =-(*(Bp1 + j1)); + }}}}}}; + break; + + case 7 : + for(i7=0, j7 = 0; i7 < ACount[6]*AStride[6]; i7+=AStride[6], j7+=BStride[6]) + { Ap6 = AOffptr + i7; Bp6 = BOffptr + j7; + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = Ap6 + i6; Bp5 = Bp6 + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) = -(*(Bp1 + j1)); + }}}}}}}; + break; + + } +} +} + +void CAMbinaryEngine::doubleAplusEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata) +{ + double* AdataP = (double*)Adata.getDataPointer(); + double* BdataP = (double*)Bdata.getDataPointer(); + + CAMdataHandler Btemporary; + if(AdataP == BdataP) + { + Btemporary.initialize(Bdata); + BdataP = (double*)Btemporary.getDataPointer(); + } + +#ifndef __NO_BLAS__ + long strideA; + long strideB; + long Size; + double dOne = 1.0; +#endif + + if((Astructure.isSubset() == 0)&&(Bstructure.isSubset() == 0)) + { +#ifdef __NO_BLAS__ + double* aptr; double* bptr; + for(aptr = AdataP, bptr = BdataP; + aptr < AdataP + Adata.getDataSize(); + aptr++, bptr++) { *aptr += *bptr; }; +#else + strideA = 1; + strideB = 1; + Size = Adata.getDataSize(); + + daxpy_(&Size,&dOne, BdataP,&strideB, AdataP, &strideA); +#endif + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + long BloopDimension; + long BOffset; + MVAlongBase BCount; + MVAlongBase BStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + Bstructure.getNormalizedLoops(BloopDimension,BOffset, BCount, BStride); + + register long i1, i2, i3, i4, i5, i6, i7; + register long j1, j2, j3, j4, j5, j6, j7; + double* AOffptr = AdataP + AOffset; + double* BOffptr = BdataP + BOffset; + + register double* Ap1; register double* Bp1; + register double* Ap2; register double* Bp2; + register double* Ap3; register double* Bp3; + register double* Ap4; register double* Bp4; + register double* Ap5; register double* Bp5; + register double* Ap6; register double* Bp6; + +#ifndef __NO_BLAS__ + strideA = AStride[0]; + strideB = BStride[0]; + Size = ACount[0]; +#endif + + switch(AloopDimension) + { + case 1 : +#ifdef __NO_BLAS__ + for(i1=0, j1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(AOffptr + i1) += + *(BOffptr + j1); + }; +#else + daxpy_(&Size,&dOne, BOffptr,&strideB, AOffptr, &strideA); +#endif + + break; + + case 2 : + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = AOffptr + i2; Bp1 = BOffptr + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) += *(Bp1 + j1); + } +#else + daxpy_(&Size,&dOne, Bp1,&strideB, Ap1, &strideA); +#endif + }; + break; + + case 3 : + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = AOffptr + i3; Bp2 = BOffptr + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) += *(Bp1 + j1); + } +#else + daxpy_(&Size,&dOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}; + break; + + case 4 : + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = AOffptr + i4; Bp3 = BOffptr + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) += *(Bp1 + j1); + } +#else + daxpy_(&Size,&dOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}; + break; + + case 5 : + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = AOffptr + i5; Bp4 = BOffptr + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) += *(Bp1 + j1); + } +#else + daxpy_(&Size,&dOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}}; + break; + + case 6 : + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = AOffptr+ i6; Bp5 = BOffptr + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) += *(Bp1 + j1); + } +#else + daxpy_(&Size,&dOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}}}; + break; + + case 7 : + for(i7=0, j7 = 0; i7 < ACount[6]*AStride[6]; i7+=AStride[6], j7+=BStride[6]) + { Ap6 = AOffptr + i7; Bp6 = BOffptr + j7; + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = Ap6 + i6; Bp5 = Bp6 + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) += *(Bp1 + j1); + } +#else + daxpy_(&Size,&dOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}}}}; + break; + + } +} + + +} + + + +void CAMbinaryEngine::doubleAminusEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata) +{ + double* AdataP = (double*)Adata.getDataPointer(); + double* BdataP = (double*)Bdata.getDataPointer(); + + CAMdataHandler Btemporary; + if(AdataP == BdataP) + { + Btemporary.initialize(Bdata); + BdataP = (double*)Btemporary.getDataPointer(); + } + +#ifndef __NO_BLAS__ + long strideA; + long strideB; + long Size; + double dNegOne = -1.0; +#endif + + if((Astructure.isSubset() == 0)&&(Bstructure.isSubset() == 0)) + { +#ifdef __NO_BLAS__ + double* aptr; double* bptr; + for(aptr = AdataP, bptr = BdataP; + aptr < AdataP + Adata.getDataSize(); + aptr++, bptr++) { *aptr -= *bptr; }; +#else + strideA = 1; + strideB = 1; + Size = Adata.getDataSize(); + + daxpy_(&Size,&dNegOne, BdataP, &strideB, AdataP,&strideA); +#endif + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + long BloopDimension; + long BOffset; + MVAlongBase BCount; + MVAlongBase BStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + Bstructure.getNormalizedLoops(BloopDimension,BOffset, BCount, BStride); + + register long i1, i2, i3, i4, i5, i6, i7; + register long j1, j2, j3, j4, j5, j6, j7; + double* AOffptr = AdataP + AOffset; + double* BOffptr = BdataP + BOffset; + + register double* Ap1; register double* Bp1; + register double* Ap2; register double* Bp2; + register double* Ap3; register double* Bp3; + register double* Ap4; register double* Bp4; + register double* Ap5; register double* Bp5; + register double* Ap6; register double* Bp6; + +#ifndef __NO_BLAS__ + strideA = AStride[0]; + strideB = BStride[0]; + Size = ACount[0]; +#endif + + switch(AloopDimension) + { + case 1 : +#ifdef __NO_BLAS__ + for(i1=0, j1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(AOffptr + i1) -= + *(BOffptr + j1); + }; +#else + daxpy_(&Size,&dNegOne, BOffptr, &strideB, AOffptr, &strideA); +#endif + + break; + + case 2 : + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = AOffptr + i2; Bp1 = BOffptr + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) -= *(Bp1 + j1); + } +#else + daxpy_(&Size,&dNegOne, Bp1,&strideB, Ap1, &strideA); +#endif + }; + break; + + case 3 : + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = AOffptr + i3; Bp2 = BOffptr + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) -= *(Bp1 + j1); + } +#else + daxpy_(&Size,&dNegOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}; + break; + + case 4 : + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = AOffptr + i4; Bp3 = BOffptr + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) -= *(Bp1 + j1); + } +#else + daxpy_(&Size,&dNegOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}; + break; + + case 5 : + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = AOffptr + i5; Bp4 = BOffptr + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) -= *(Bp1 + j1); + } +#else + daxpy_(&Size,&dNegOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}}; + break; + + case 6 : + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = AOffptr+ i6; Bp5 = BOffptr + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) -= *(Bp1 + j1); + } +#else + daxpy_(&Size,&dNegOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}}}; + break; + + case 7 : + for(i7=0, j7 = 0; i7 < ACount[6]*AStride[6]; i7+=AStride[6], j7+=BStride[6]) + { Ap6 = AOffptr + i7; Bp6 = BOffptr + j7; + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = Ap6 + i6; Bp5 = Bp6 + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; +#ifdef __NO_BLAS__ + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) -= *(Bp1 + j1); + } +#else + daxpy_(&Size,&dNegOne, Bp1,&strideB, Ap1, &strideA); +#endif + }}}}}}; + break; + + } +} + + +} + + +void CAMbinaryEngine::doubleAtimesEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata) +{ + double* AdataP = (double*)Adata.getDataPointer(); + double* BdataP = (double*)Bdata.getDataPointer(); + + CAMdataHandler Btemporary; + if(AdataP == BdataP) + { + Btemporary.initialize(Bdata); + BdataP = (double*)Btemporary.getDataPointer(); + } + + if((Astructure.isSubset() == 0)&&(Bstructure.isSubset() == 0)) + { + double* aptr; double* bptr; + for(aptr = AdataP, bptr = BdataP; + aptr < AdataP + Adata.getDataSize(); + aptr++, bptr++) { *aptr *= *bptr; }; + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + long BloopDimension; + long BOffset; + MVAlongBase BCount; + MVAlongBase BStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + Bstructure.getNormalizedLoops(BloopDimension,BOffset, BCount, BStride); + + register long i1, i2, i3, i4, i5, i6, i7; + register long j1, j2, j3, j4, j5, j6, j7; + double* AOffptr = AdataP + AOffset; + double* BOffptr = BdataP + BOffset; + + register double* Ap1; register double* Bp1; + register double* Ap2; register double* Bp2; + register double* Ap3; register double* Bp3; + register double* Ap4; register double* Bp4; + register double* Ap5; register double* Bp5; + register double* Ap6; register double* Bp6; + + switch(AloopDimension) + { + case 1 : + + for(i1=0, j1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(AOffptr + i1) *= *(BOffptr + j1); + }; + + break; + + case 2 : + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = AOffptr + i2; Bp1 = BOffptr + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) *= *(Bp1 + j1); + } + }; + break; + + case 3 : + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = AOffptr + i3; Bp2 = BOffptr + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) *= *(Bp1 + j1); + } + }}; + break; + + case 4 : + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = AOffptr + i4; Bp3 = BOffptr + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) *= *(Bp1 + j1); + } + }}}; + break; + + case 5 : + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = AOffptr + i5; Bp4 = BOffptr + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) *= *(Bp1 + j1); + } + }}}}; + break; + + case 6 : + + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = AOffptr+ i6; Bp5 = BOffptr + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) *= *(Bp1 + j1); + } + }}}}}; + break; + + case 7 : + for(i7=0, j7 = 0; i7 < ACount[6]*AStride[6]; i7+=AStride[6], j7+=BStride[6]) + { Ap6 = AOffptr + i7; Bp6 = BOffptr + j7; + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = Ap6 + i6; Bp5 = Bp6 + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) *= *(Bp1 + j1); + } + }}}}}}; + break; + + } +} +} + + +void CAMbinaryEngine::doubleAdivideEqualB(CAMstructureBase &Astructure, CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata) +{ + double* AdataP = (double*)Adata.getDataPointer(); + double* BdataP = (double*)Bdata.getDataPointer(); + + CAMdataHandler Btemporary; + if(AdataP == BdataP) + { + Btemporary.initialize(Bdata); + BdataP = (double*)Btemporary.getDataPointer(); + } + + if((Astructure.isSubset() == 0)&&(Bstructure.isSubset() == 0)) + { + double* aptr; double* bptr; + for(aptr = AdataP, bptr = BdataP; + aptr < AdataP + Adata.getDataSize(); + aptr++, bptr++) { *aptr /= *bptr; }; + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + long BloopDimension; + long BOffset; + MVAlongBase BCount; + MVAlongBase BStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + Bstructure.getNormalizedLoops(BloopDimension,BOffset, BCount, BStride); + + register long i1, i2, i3, i4, i5, i6, i7; + register long j1, j2, j3, j4, j5, j6, j7; + double* AOffptr = AdataP + AOffset; + double* BOffptr = BdataP + BOffset; + + register double* Ap1; register double* Bp1; + register double* Ap2; register double* Bp2; + register double* Ap3; register double* Bp3; + register double* Ap4; register double* Bp4; + register double* Ap5; register double* Bp5; + register double* Ap6; register double* Bp6; + switch(AloopDimension) + { + case 1 : + + for(i1=0, j1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(AOffptr + i1) /= *(BOffptr + j1); + }; + + break; + + case 2 : + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = AOffptr + i2; Bp1 = BOffptr + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) /= *(Bp1 + j1); + } + }; + break; + + case 3 : + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = AOffptr + i3; Bp2 = BOffptr + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) /= *(Bp1 + j1); + } + }}; + break; + + case 4 : + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = AOffptr + i4; Bp3 = BOffptr + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) /= *(Bp1 + j1); + } + }}}; + break; + + case 5 : + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = AOffptr + i5; Bp4 = BOffptr + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) /= *(Bp1 + j1); + } + }}}}; + break; + + case 6 : + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = AOffptr+ i6; Bp5 = BOffptr + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) /= *(Bp1 + j1); + } + }}}}}; + break; + + case 7 : + for(i7=0, j7 = 0; i7 < ACount[6]*AStride[6]; i7+=AStride[6], j7+=BStride[6]) + { Ap6 = AOffptr + i7; Bp6 = BOffptr + j7; + for(i6=0, j6 = 0; i6 < ACount[5]*AStride[5]; i6+=AStride[5], j6+=BStride[5]) + { Ap5 = Ap6 + i6; Bp5 = Bp6 + j6; + for(i5=0, j5 = 0; i5 < ACount[4]*AStride[4]; i5+=AStride[4], j5+=BStride[4]) + { Ap4 = Ap5 + i5; Bp4 = Bp5 + j5; + for(i4=0, j4 = 0; i4 < ACount[3]*AStride[3]; i4+=AStride[3], j4+=BStride[3]) + { Ap3 = Ap4 + i4; Bp3 = Bp4 + j4; + for(i3=0, j3 = 0; i3 < ACount[2]*AStride[2]; i3+=AStride[2], j3+=BStride[2]) + { Ap2 = Ap3 + i3; Bp2 = Bp3 + j3; + for(i2=0, j2 = 0; i2 < ACount[1]*AStride[1]; i2+=AStride[1], j2+=BStride[1]) + { Ap1 = Ap2 + i2; Bp1 = Bp2 + j2; + for(i1=0, j1 = 0; i1 < ACount[0]*AStride[0]; i1+=AStride[0], j1+=BStride[0]) + { + *(Ap1 + i1) /= *(Bp1 + j1); + } + }}}}}}; + break; + + } +} +} + + + + +void CAMbinaryEngine::doubleCequalAplusB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, +CAMstructureBase &Cstructure, CAMdataHandler &Cdata) +{ + CAMbinaryEngine::doubleAequalToB(Cstructure, Cdata, Astructure, Adata); + CAMbinaryEngine::doubleAplusEqualB(Cstructure, Cdata, Bstructure, Bdata); +} + +void CAMbinaryEngine::doubleCequalAminusB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, +CAMstructureBase &Cstructure, CAMdataHandler &Cdata) +{ + CAMbinaryEngine::doubleAequalToB(Cstructure, Cdata, Astructure, Adata); + CAMbinaryEngine::doubleAminusEqualB(Cstructure, Cdata, Bstructure, Bdata); +} + +void CAMbinaryEngine::doubleCequalAtimesB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, +CAMstructureBase &Cstructure, CAMdataHandler &Cdata) +{ + CAMbinaryEngine::doubleAequalToB(Cstructure, Cdata, Astructure, Adata); + CAMbinaryEngine::doubleAtimesEqualB(Cstructure, Cdata, Bstructure, Bdata); +} + +void CAMbinaryEngine::doubleCequalAdivideB(const CAMstructureBase &Astructure, const CAMdataHandler &Adata, +const CAMstructureBase &Bstructure, const CAMdataHandler &Bdata, +CAMstructureBase &Cstructure, CAMdataHandler &Cdata) +{ + CAMbinaryEngine::doubleAequalToB(Cstructure, Cdata, Astructure, Adata); + CAMbinaryEngine::doubleAdivideEqualB(Cstructure, Cdata, Bstructure, Bdata); +} + + diff --git a/src/matrix/dbengneb.cpp b/src/matrix/dbengneb.cpp new file mode 100755 index 0000000..aa5f5fd --- /dev/null +++ b/src/matrix/dbengneb.cpp @@ -0,0 +1,522 @@ +#include "bnengine.h" +#include "strctbse.h" +#include "datahndl.h" +#include "math.h" +#include "blas.h" + +void CAMbinaryEngine::doubleAequalToAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, +double alpha) +{ + double* AdataP = (double*)Adata.getDataPointer(); + +#ifndef __NO_BLAS__ + long strideA; + long Size; + long longZero = 0; +#endif + + if(Astructure.isSubset() == 0) + { +#ifdef __NO_BLAS__ + double* aptr; + for(aptr = AdataP; aptr < AdataP + Adata.getDataSize(); aptr++) + { *aptr = alpha; }; +#else + strideA = 1; + Size = Adata.getDataSize(); + dcopy_(&Size,&alpha,&longZero, AdataP, &strideA); +#endif + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + + register long i1, i2, i3, i4, i5, i6, i7; + + double* AOffptr = AdataP + AOffset; + + register double* Ap1; + register double* Ap2; + register double* Ap3; + register double* Ap4; + register double* Ap5; + register double* Ap6; + +#ifndef __NO_BLAS__ + strideA = AStride[0]; + Size = ACount[0]; +#endif + + switch(AloopDimension) + { + case 1 : +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(AOffptr + i1) = alpha;}; +#else + dcopy_(&Size,&alpha,&longZero, AOffptr, &strideA); +#endif + + break; + + case 2 : + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = AOffptr + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) = alpha;}; +#else + dcopy_(&Size,&alpha,&longZero, Ap1, &strideA); +#endif + }; + break; + + case 3 : + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = AOffptr + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) = alpha;}; +#else + dcopy_(&Size,&alpha,&longZero, Ap1, &strideA); +#endif + }}; + break; + + case 4 : + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = AOffptr + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) = alpha;}; +#else + dcopy_(&Size,&alpha,&longZero, Ap1, &strideA); +#endif + }}}; + break; + + case 5 : + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = AOffptr + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) = alpha;}; +#else + dcopy_(&Size,&alpha,&longZero, Ap1, &strideA); +#endif + }}}}; + break; + + case 6 : + for(i6=0; i6 < ACount[5]*AStride[5]; i6+=AStride[5]) + { Ap5 = AOffptr+ i6; + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = Ap5 + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) = alpha;}; +#else + dcopy_(&Size,&alpha,&longZero, Ap1, &strideA); +#endif + }}}}}; + break; + + case 7 : + for(i7=0; i7 < ACount[6]*AStride[6]; i7+=AStride[6]) + { Ap6 = AOffptr + i7; + for(i6=0; i6 < ACount[5]*AStride[5]; i6+=AStride[5]) + { Ap5 = Ap6 + i6; + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = Ap5 + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) = alpha;}; +#else + dcopy_(&Size,&alpha,&longZero, Ap1, &strideA); +#endif + }}}}}}; + break; + + } +} + +} + + +void CAMbinaryEngine::doubleAplusEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, +double alpha) +{ + double* AdataP = (double*)Adata.getDataPointer(); + +#ifndef __NO_BLAS__ + long strideA; + long Size; + long longZero = 0; + double dOne = 1.0; +#endif + + if(Astructure.isSubset() == 0) + { +#ifdef __NO_BLAS__ + double* aptr; + for(aptr = AdataP; aptr < AdataP + Adata.getDataSize(); aptr++) + { *aptr += alpha; }; +#else + strideA = 1; + Size = Adata.getDataSize(); + daxpy_(&Size,&dOne, &alpha,&longZero, AdataP, &strideA); +#endif + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + + register long i1, i2, i3, i4, i5, i6, i7; + + double* AOffptr = AdataP + AOffset; + + register double* Ap1; + register double* Ap2; + register double* Ap3; + register double* Ap4; + register double* Ap5; + register double* Ap6; + +#ifndef __NO_BLAS__ + strideA = AStride[0]; + Size = ACount[0]; +#endif + + switch(AloopDimension) + { + case 1 : +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(AOffptr + i1) += alpha;}; +#else + daxpy_(&Size,&dOne,&alpha,&longZero, AOffptr, &strideA); +#endif + + break; + + case 2 : + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = AOffptr + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) += alpha;}; +#else + daxpy_(&Size, &dOne, &alpha,&longZero, Ap1, &strideA); +#endif + }; + break; + + case 3 : + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = AOffptr + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) += alpha;}; +#else + daxpy_(&Size, &dOne, &alpha,&longZero, Ap1, &strideA); +#endif + }}; + break; + + case 4 : + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = AOffptr + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) += alpha;}; +#else + daxpy_(&Size, &dOne, &alpha,&longZero, Ap1, &strideA); +#endif + }}}; + break; + + case 5 : + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = AOffptr + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) += alpha;}; +#else + daxpy_(&Size, &dOne, &alpha,&longZero, Ap1, &strideA); +#endif + }}}}; + break; + + case 6 : + for(i6=0; i6 < ACount[5]*AStride[5]; i6+=AStride[5]) + { Ap5 = AOffptr+ i6; + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = Ap5 + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1) += alpha;}; +#else + daxpy_(&Size, &dOne, &alpha,&longZero, Ap1, &strideA); +#endif + }}}}}; + break; + + case 7 : + for(i7=0; i7 < ACount[6]*AStride[6]; i7+=AStride[6]) + { Ap6 = AOffptr + i7; + for(i6=0; i6 < ACount[5]*AStride[5]; i6+=AStride[5]) + { Ap5 = Ap6 + i6; + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = Ap5 + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; +#ifdef __NO_BLAS__ + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1 ) += alpha;}; +#else + daxpy_(&Size, &dOne, &alpha,&longZero, Ap1, &strideA); +#endif + }}}}}}; + break; + + } +} + +} + +void CAMbinaryEngine::doubleAtimesEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, +double alpha) +{ + double* AdataP = (double*)Adata.getDataPointer(); + + if(Astructure.isSubset() == 0) + { + double* aptr; + for(aptr = AdataP; aptr < AdataP + Adata.getDataSize(); aptr++) + { *aptr *= alpha; }; + } + else + { +// +// Get Normalized Loops +// + long AloopDimension; + long AOffset; + MVAlongBase ACount; + MVAlongBase AStride; + + Astructure.getNormalizedLoops(AloopDimension,AOffset, ACount, AStride); + + register long i1, i2, i3, i4, i5, i6, i7; + + double* AOffptr = AdataP + AOffset; + + register double* Ap1; + register double* Ap2; + register double* Ap3; + register double* Ap4; + register double* Ap5; + register double* Ap6; + + switch(AloopDimension) + { + case 1 : + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(AOffptr + i1) *= alpha;}; + break; + + case 2 : + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = AOffptr + i2; + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1 ) *= alpha;}; + }; + break; + + case 3 : + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = AOffptr + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1 ) *= alpha;}; + }}; + break; + + case 4 : + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = AOffptr + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1 ) *= alpha;}; + }}}; + break; + + case 5 : + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = AOffptr + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1 ) *= alpha;}; + }}}}; + break; + + case 6 : + for(i6=0; i6 < ACount[5]*AStride[5]; i6+=AStride[5]) + { Ap5 = AOffptr+ i6; + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = Ap5 + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1 ) *= alpha;}; + }}}}}; + break; + + case 7 : + for(i7=0; i7 < ACount[6]*AStride[6]; i7+=AStride[6]) + { Ap6 = AOffptr + i7; + for(i6=0; i6 < ACount[5]*AStride[5]; i6+=AStride[5]) + { Ap5 = Ap6 + i6; + for(i5=0; i5 < ACount[4]*AStride[4]; i5+=AStride[4]) + { Ap4 = Ap5 + i5; + for(i4=0; i4 < ACount[3]*AStride[3]; i4+=AStride[3]) + { Ap3 = Ap4 + i4; + for(i3=0; i3 < ACount[2]*AStride[2]; i3+=AStride[2]) + { Ap2 = Ap3 + i3; + for(i2=0; i2 < ACount[1]*AStride[1]; i2+=AStride[1]) + { Ap1 = Ap2 + i2; + for(i1=0; i1 < ACount[0]*AStride[0]; i1+=AStride[0]) + {*(Ap1 + i1 ) *= alpha;}; + }}}}}}; + break; + + } +} + +} + +void CAMbinaryEngine::doubleAminusEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, +double alpha) +{CAMbinaryEngine::doubleAplusEqualAlpha(Astructure, Adata, -alpha);} + +void CAMbinaryEngine::doubleAdivideEqualAlpha(CAMstructureBase &Astructure, CAMdataHandler &Adata, +double alpha) +{CAMbinaryEngine::doubleAtimesEqualAlpha(Astructure, Adata, 1.0/alpha);} + +// +// Array Utilities + +void CAMbinaryEngine::doubleMaxValue(double* data, long n, double& maxValue) +{ + long i; + maxValue = *data; + for(i = 1; i < n; i++) + if(maxValue < *(data + i)) maxValue = *(data + i); +} +void CAMbinaryEngine::doubleMinValue(double* data, long n, double& minValue) +{ + long i; + minValue = *data; + for(i = 1; i < n; i++) + if(minValue > *(data + i)) minValue = *(data + i); +} +void CAMbinaryEngine::doubleMaxAbsValue(double* data, long n, double& maxAbsValue) +{ + long i; + maxAbsValue = fabs(*data); + for(i = 1; i < n; i++) + if(maxAbsValue < fabs(*(data + i))) maxAbsValue = fabs(*(data + i)); +} +void CAMbinaryEngine::doubleMinAbsValue(double* data, long n, double& minAbsValue) +{ + long i; + minAbsValue = fabs(*data); + for(i = 1; i < n; i++) + if(minAbsValue > fabs(*(data + i))) minAbsValue = fabs(*(data + i)); +} + +void CAMbinaryEngine::doublepNorm(double* data, long n, double p, double& pNormValue) +{ + pNormValue = 0.0; + double* dptr; + for(dptr = (double*)data; dptr < (double*)data + n; dptr++) + pNormValue += ::pow(fabs(*(dptr)),p); + + pNormValue = ::pow(pNormValue,1.0/p); +} + diff --git a/src/matrix/dmatrix.cpp b/src/matrix/dmatrix.cpp new file mode 100755 index 0000000..f1a1f0f --- /dev/null +++ b/src/matrix/dmatrix.cpp @@ -0,0 +1,18 @@ +// +// DMATRIX.CPP +// +// Chris Anderson (C) UCLA 1995 +// +#include "dmatrix.h" + +CAMdoubleMatrix CAMdoubleMatrix::identity(long n) +{ + CAMdoubleMatrix I(n,n); + for(long i = 1; i <= n; i++) + I(i,i) = 1.0; + I.setTemporaryFlag(); + return I; +} + + + diff --git a/src/matrix/dmatrix.h b/src/matrix/dmatrix.h new file mode 100755 index 0000000..5a12006 --- /dev/null +++ b/src/matrix/dmatrix.h @@ -0,0 +1,149 @@ +// +//****************************************************************************** +// DMATRIX.H +//****************************************************************************** +// + +#include "strctbse.h" +#include "datahndl.h" +#include "matbse.h" +#include "vecbse.h" +#include "range.h" +#include "camtype.h" +#include "under.h" + +// +// +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Thu Nov 02 13:42:45 1995 +// +//******************************************************************************** +// + +#ifndef _CAMDOUBLEMATRIX_ +#define _CAMDOUBLEMATRIX_ + +#include "mvaimpexp.h" + +class __IMPEXP__ CAMdoubleMatrix : public CAMmatrixBase +{ + +public : + +// +// Constructors +// + CAMdoubleMatrix():CAMmatrixBase(CAMType::typeDouble){}; + CAMdoubleMatrix(const CAMdoubleMatrix& A):CAMmatrixBase(*((CAMmatrixBase*)&A)){}; + CAMdoubleMatrix(const CAMmatrixBase& A):CAMmatrixBase(A){}; + CAMdoubleMatrix(const CAMrange& R1, const CAMrange& R2) + : CAMmatrixBase(CAMType::typeDouble,R1, R2){}; +// +// Assignment +// + void operator = (const CAMdoubleMatrix& A) + {CAMmatrixBase* basePtr = this; const CAMmatrixBase* AbasePtr = + (CAMmatrixBase*)&A; basePtr->operator=(*AbasePtr);}; + void operator =( const CAMmatrixBase& A) + {CAMmatrixBase* basePtr = this; basePtr->operator=(A);}; + void operator = (const CAMvectorBase& A) + {CAMmatrixBase* basePtr = this; basePtr->operator=(A);}; + void operator = (double value) + {CAMmatrixBase* basePtr = this; basePtr->operator=(value);}; +// +// initialization +// + void initialize() + {CAMmatrixBase* basePtr = this; basePtr->initialize(CAMType::typeDouble);}; + void initialize(const CAMdoubleMatrix& A) + {CAMmatrixBase* basePtr = this; basePtr->initialize(A);}; + void initialize(const CAMmatrixBase& A) + {CAMmatrixBase* basePtr = this; basePtr->initialize(A);}; + void initialize(const CAMrange& R1, const CAMrange& R2) + {CAMmatrixBase* basePtr = this; basePtr->initialize(CAMType::typeDouble,R1, R2);}; +// +// Access Functions +// + inline double& operator()(long i1, long i2) +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMmatrixBase::indexCheck(Structure,i1,i2); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + + long offset = + (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)*(i2 - *(beginPtr +1)); + + return (*(dataPtr + offset)); +}; + inline const double& operator()(long i1, long i2) const +{ +#ifndef _NO_BOUNDS_CHECK_ + CAMmatrixBase::indexCheck(Structure,i1,i2); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + + long offset = + (i1 - *(beginPtr)) + + ((*endPtr - *beginPtr) + 1)*(i2 - *(beginPtr +1)); + + return (*(dataPtr + offset)); +}; + const CAMdoubleMatrix operator()(const CAMrange& R1, const CAMrange& R2) const +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2); + CAMdoubleMatrix A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; + CAMdoubleMatrix operator() (const CAMrange& R1, const CAMrange& R2) +{ + CAMstructureBase Rstructure(Structure); + Rstructure.setStructureSubset(R1,R2); + CAMdoubleMatrix A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +}; +// +// data pointer access +// + double* getDataPointer() const {return (double*)DataP->getDataPointer();}; +// +// Double Matrix Specific Utility Routines +// + static CAMdoubleMatrix identity(long n); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + + + diff --git a/src/matrix/dvector.h b/src/matrix/dvector.h new file mode 100755 index 0000000..cd0f443 --- /dev/null +++ b/src/matrix/dvector.h @@ -0,0 +1,168 @@ +// +//****************************************************************************** +// DVECTOR.H +//****************************************************************************** +// + +#include "strctbse.h" +#include "datahndl.h" +#include "vecbse.h" +#include "matbse.h" +#include "range.h" +#include "camtype.h" +#include "under.h" + +// +// +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Thu Nov 02 13:42:45 1995 +// +//******************************************************************************** +// + +#ifndef _CAMDOUBLEVECTOR_ +#define _CAMDOUBLEVECTOR_ + +#include "mvaimpexp.h" + +class __IMPEXP__ CAMdoubleVector : public CAMvectorBase +{ + +public : +// +// Constructors +// + CAMdoubleVector():CAMvectorBase(CAMType::typeDouble){}; + CAMdoubleVector(const CAMdoubleVector& A):CAMvectorBase(*((CAMvectorBase*)&A)){}; + CAMdoubleVector(const CAMvectorBase& A):CAMvectorBase(A){}; + CAMdoubleVector(long n):CAMvectorBase(CAMType::typeDouble, n){}; + CAMdoubleVector(const CAMrange& R1) + : CAMvectorBase(CAMType::typeDouble,R1){}; + CAMdoubleVector(const CAMrange& R1,char* RorC) + : CAMvectorBase(CAMType::typeDouble,R1) + {if(RorC[0] == 'r') (*this).initialize(this->transpose());}; +// +// Assignment +// + void operator = (const CAMdoubleVector& A) + {CAMvectorBase* basePtr = this; const CAMvectorBase* AbasePtr = + (CAMvectorBase*)&A; basePtr->operator=(*AbasePtr);}; + void operator =( const CAMvectorBase& A) + {CAMvectorBase* basePtr = this; basePtr->operator=(A);}; + void operator = (const CAMmatrixBase& A) + {CAMvectorBase* basePtr = this; basePtr->operator=(A);}; + void operator = (double value) + {CAMvectorBase* basePtr = this; basePtr->operator=(value);}; +// +// initialization +// + void initialize() + {CAMvectorBase* basePtr = this; basePtr->initialize(CAMType::typeDouble);}; + void initialize(const CAMdoubleVector& A) + {CAMvectorBase* basePtr = this; basePtr->initialize(A);}; + void initialize(const CAMvectorBase& A) + {CAMvectorBase* basePtr = this; basePtr->initialize(A);}; + void initialize(long n) + {CAMvectorBase* basePtr = this; basePtr->initialize(CAMType::typeDouble, n);}; + void initialize(const CAMrange& R1) + {CAMvectorBase* basePtr = this; basePtr->initialize(CAMType::typeDouble,R1);}; + inline double& operator()(long i1) +{ +#ifndef _NO_BOUNDS_CHECK_ + long ia, ib; + if(Structure[1].getIndexCount() != 1) + {ia = i1; ib = Structure[2].getIndexBase();} + else + {ia = Structure[1].getIndexBase(); ib = i1;} + CAMvectorBase::indexCheck(Structure,ia,ib); +#endif + long* beginPtr = Structure.indexBeginBase.getDataPointer(); + + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)); + return *(dataPtr + offset); +} + inline const double& operator()(long i1) const +{ +#ifndef _NO_BOUNDS_CHECK_ + long ia, ib; + if(Structure[1].getIndexCount() != 1) + {ia = i1; ib = Structure[2].getIndexBase();} + else + {ia = Structure[1].getIndexBase(); ib = i1;} + CAMvectorBase::indexCheck(Structure,ia,ib); +#endif + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + double* dataPtr = (double*)DataP->dataPointer; + long offset = (i1 - *(beginPtr)); + return (*(dataPtr + offset)); +}; + CAMdoubleVector operator() (const CAMrange& R1) +{ + CAMstructureBase Rstructure(Structure); + CAMrange Ra, Rb; + if(Structure[1].getIndexCount() != 1) + { + Ra = R1; + Rb.initialize(Structure[2].getIndexBase(),Structure[2].getIndexBase()); + } + else + { + Ra.initialize(Structure[1].getIndexBase(),Structure[1].getIndexBase()); + Rb = R1; + } + Rstructure.setStructureSubset(Ra,Rb); + CAMdoubleVector A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +} + const CAMdoubleVector operator()(const CAMrange& R1) const +{ + CAMstructureBase Rstructure(Structure); + CAMrange Ra, Rb; + if(Structure[1].getIndexCount() != 1) + { + Ra = R1; + Rb.initialize(Structure[2].getIndexBase(),Structure[2].getIndexBase()); + } + else + { + Ra.initialize(Structure[1].getIndexBase(),Structure[1].getIndexBase()); + Rb = R1; + } + Rstructure.setStructureSubset(Ra,Rb); + CAMdoubleVector A; + A.Structure.initialize(Rstructure); + A.DataP = DataP; + A.DataP->incrementReferenceCount(); + A.DataP->incrementReferenceCount(); + A.referenceFlag = 1; + return A; +} +// +// data pointer access +// + double* getDataPointer() const {return (double*)DataP->getDataPointer();}; + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + + + diff --git a/src/matrix/makeGraphics b/src/matrix/makeGraphics new file mode 100755 index 0000000..a5b8a40 --- /dev/null +++ b/src/matrix/makeGraphics @@ -0,0 +1,21 @@ +# +# Sample Make file for Matrix/Vector/Array Graphics +# +# Note : This appends the graphics routines to the CAM matrix/vector/array +# library. +# +CC = CC +cc = cc +DEFINES = __STATIC__ +CCFLAGS = +INCLUDES = -I../camgraph +LIBRARY = libcammva.a + +.SUFFIXES: .o .cpp .a # define suffix rules so it knows what to + # do with .cpp files ... +$(LIBRARY): mvagph.o + ar ru $(LIBRARY) mvagph.o + rm *.o + +.cpp.o : + $(CC) $(CCFLAGS) -D$(DEFINES) $(INCLUDES) -c $< diff --git a/src/matrix/makeGraphicsGPP b/src/matrix/makeGraphicsGPP new file mode 100755 index 0000000..37f07f0 --- /dev/null +++ b/src/matrix/makeGraphicsGPP @@ -0,0 +1,21 @@ +# +# Sample Make file for Matrix/Vector/Array Graphics +# +# Note : This appends the graphics routines to the CAM matrix/vector/array +# library. +# +CC = g++ +cc = gcc +DEFINES = __STATIC__ +CCFLAGS = +INCLUDES = -I../camgraph +LIBRARY = libcammva.a + +.SUFFIXES: .o .cpp .a # define suffix rules so it knows what to + # do with .cpp files ... +$(LIBRARY): mvagph.o + ar ru $(LIBRARY) mvagph.o + rm *.o + +.cpp.o : + $(CC) $(CCFLAGS) -D$(DEFINES) $(INCLUDES) -c $< diff --git a/src/matrix/makeSamples b/src/matrix/makeSamples new file mode 100755 index 0000000..1b6bedc --- /dev/null +++ b/src/matrix/makeSamples @@ -0,0 +1,18 @@ +# +# Make file for sample programs +# + +all : mvasamp1.o mvasamp2.o mvasamp3.o + + +mvasamp1.o : + CC mvasamp1.cpp -L. -lcammva -o mvasamp1 + +mvasamp2.o : + CC mvasamp2.cpp -L. -lcammva -o mvasamp2 + +mvasamp3.o : + CC mvasamp3.cpp -L. -lcammva -o mvasamp3 + + + diff --git a/src/matrix/makeSamplesGPP b/src/matrix/makeSamplesGPP new file mode 100755 index 0000000..f048b63 --- /dev/null +++ b/src/matrix/makeSamplesGPP @@ -0,0 +1,18 @@ +# +# Make file for sample programs +# + +all : mvasamp1.o mvasamp2.o mvasamp3.o + + +mvasamp1.o : + g++ mvasamp1.cpp -L. -lcammva -o mvasamp1 + +mvasamp2.o : + g++ mvasamp2.cpp -L. -lcammva -o mvasamp2 + +mvasamp3.o : + g++ mvasamp3.cpp -L. -lcammva -o mvasamp3 + + + diff --git a/src/matrix/matbse.cpp b/src/matrix/matbse.cpp new file mode 100755 index 0000000..3efbe70 --- /dev/null +++ b/src/matrix/matbse.cpp @@ -0,0 +1,1552 @@ +#include "arraybse.h" +#include "vecbse.h" +#include "matbse.h" +#include "vecbse.h" +#include "bnengine.h" +#include "blas.h" +// +//*************************************************************** +// MATBSE.CPP +//*************************************************************** +// +// +//***************************************************************** +// +// Chris Anderson +// +// Mon Sep 11 12:49:20 1995 +// +//***************************************************************** +// +// +//***************************************************************** +// CONSTRUCTORS +//***************************************************************** +// +// +//***************************************************************** +// +//***************************************************************** +// +CAMmatrixBase::CAMmatrixBase() +: Structure() +{ + DataP = 0; + typeValue = 0; + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + +CAMmatrixBase::CAMmatrixBase(int d_type) +: Structure() +{ + DataP = 0; + typeValue = d_type; + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + +CAMmatrixBase::CAMmatrixBase(const CAMmatrixBase& A) +:Structure(A.Structure) +{ + if(A.DataP == 0) + {DataP = 0;} + else + { + if(A.referenceFlag == 1) + {DataP = A.DataP; } + else if(A.DataP->getTemporaryFlag() == 1) + { + DataP = new CAMdataHandler(*(A.DataP)); + DataP ->setReferenceCount(1); + } + else + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); + // + // copy based on type + // + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); + // + // + // + } + } + typeValue = A.typeValue; + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + + +// +// Constructors +// + +CAMmatrixBase::CAMmatrixBase(int d_type, const CAMrange& R1, const CAMrange& R2) +:Structure(R1,R2) +{ + DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type); + DataP->setReferenceCount(1); + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + +// +//***************************************************************** +// DESTRUCTOR +//***************************************************************** +// +CAMmatrixBase::~CAMmatrixBase() +{ + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() < 0) + { + cerr << " Error : Reference Count < 0" << endl; + } + if(DataP->getReferenceCount() == 0) delete DataP; + } +} +void CAMmatrixBase::operator =(double value) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + Structure.initialize(_(1,1),_(1,1)); + DataP = new CAMdataHandler(1,CAMType::typeDouble); + DataP->setReferenceCount(1); + referenceFlag = 0; + matrixBaseReferenceCount = 0; + } + else + { + CAMstructureBase AStructure(_(1,1),_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,AStructure);} + } + + CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value); +} +void CAMmatrixBase::operator =( const CAMmatrixBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),typeValue); + DataP->setReferenceCount(1); + typeValue = CAMType::typeDouble; + referenceFlag = 0; + matrixBaseReferenceCount = 0; + } + else + { + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + } + + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMmatrixBase::operator =( const CAMvectorBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),typeValue); + DataP->setReferenceCount(1); + typeValue = CAMType::typeDouble; + referenceFlag = 0; + matrixBaseReferenceCount = 0; + } + else + { + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + } + + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); +} +// +//******************************************************************************** +// OUTPUT +//******************************************************************************** +// +ostream& operator <<(ostream& out_stream, const CAMmatrixBase& A) +{ + const long* beginPtr = A.Structure.indexBegin.getDataPointer(); + const long* endPtr = A.Structure.indexEnd.getDataPointer(); + const long* stridePtr = A.Structure.indexStride.getDataPointer(); + + int saveWidth=out_stream.width(); + double OutValue; + + long i1, i2; + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + for(i2 = *(beginPtr+1); i2 <= *(endPtr +1); i2 += *(stridePtr+1)) + { + + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + +// out_stream << *((double*)A.getDataPointer(i1,i2)) << " "; + } + + out_stream << endl; + } + return(out_stream); + +} +istream& operator >>(istream& in_stream, CAMmatrixBase& A) +{ + const long* beginPtr = A.Structure.indexBegin.getDataPointer(); + const long* endPtr = A.Structure.indexEnd.getDataPointer(); + const long* stridePtr = A.Structure.indexStride.getDataPointer(); + + long i1, i2; + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + for(i2 = *(beginPtr+1); i2 <= *(endPtr +1); i2 += *(stridePtr+1)) + { + + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2)))) + CAMarrayBase::inputSizeError(); + +// in_stream << *((double*)A.getDataPointer(i1,i2)) << " "; + }} + return(in_stream); + +} + +// +//***************************************************************** +// INITIALIZATION MEMBER_FUNCTIONS +//***************************************************************** +// + +void CAMmatrixBase::initialize() +{ + Structure.initialize(); + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + DataP = 0; + typeValue = 0; + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + +void CAMmatrixBase::initialize(int d_type) +{ + Structure.initialize(); + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + DataP = 0; + typeValue = d_type; + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + +void CAMmatrixBase::initialize(const CAMmatrixBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + if(A.DataP != 0) + { + A.Structure.initializeMinStructure(Structure); + + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); + } + else + { + DataP = 0; + Structure.initialize(); + } + + typeValue = A.typeValue; + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + +void CAMmatrixBase::initialize(int d_type, const CAMrange& R1, const CAMrange& R2) +{ + Structure.initialize(R1,R2); + + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type); + DataP->setReferenceCount(1); + referenceFlag = 0; + matrixBaseReferenceCount = 0; +} + +// +//*************************************************************** +// ARRAYOPS.CPP +//*************************************************************** +// +// +//***************************************************************** +// +void CAMmatrixBase::initializeReturnArgument(const CAMmatrixBase& A) +{ + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); +} +void CAMmatrixBase::initializeReturnArgument(const CAMstructureBase& S, int dataT) +{ + S.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(), dataT); + DataP->setReferenceCount(1); +} +void CAMmatrixBase::initializeMinDuplicate(const CAMmatrixBase& A) +{ + + if(A.DataP == 0) return; + + long i; + long icount = 0; + long dimension = 0; + + for(i = 1; i <= A.Structure.getDimension(); i++) + if(A.Structure[i].getIndexCount() != 1) dimension++; + + + if(dimension == 0) dimension = 1; + Structure.initialize(dimension); + + + for(i = 1; i <= A.Structure.getDimension(); i++) + { + if(A.Structure[i].getIndexCount() != 1) + { + Structure.indexBegin[icount] = 1; + Structure.indexBeginBase[icount] = 1; + Structure.indexEndBase[icount] = A.Structure[i].getIndexCount(); + Structure.indexEnd[icount] = A.Structure[i].getIndexCount(); + Structure.indexStride[icount] = 1; + icount++; + } + } + + if(icount == 0) + { + Structure.indexBegin[icount] = 1; + Structure.indexBeginBase[icount] = 1; + Structure.indexEndBase[icount] = 1; + Structure.indexEnd[icount] = 1; + Structure.indexStride[icount] = 1; + } + DataP = new CAMdataHandler(Structure.getFullDataCount(), A.typeValue); + DataP->setReferenceCount(1); +// +// copy over data +// + *this = A; +} +// +//***************************************************************** +// Operators +//***************************************************************** +// +CAMmatrixBase CAMmatrixBase::operator-() const +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S; + S.initializeReturnArgument(*this); + + CAMbinaryEngine::doubleAequalToMinusB(S.Structure, *S.DataP, Structure, *DataP); + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMmatrixBase::operator+(const CAMmatrixBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMmatrixBase::operator+(const CAMvectorBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMmatrixBase CAMmatrixBase::operator-(const CAMmatrixBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAminusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMmatrixBase CAMmatrixBase::operator-(const CAMvectorBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAminusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMmatrixBase CAMmatrixBase::operator*(const CAMmatrixBase& A) const +{ + if(Structure.isMatrixOpConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// +// +// Prepare Operands +// + int STempFlag = 0; + int TTempFlag = 0; + + CAMmatrixBase* S; + CAMmatrixBase* T; + + if(Structure.isSubset() == 0) + { S = (CAMmatrixBase*)this;} + else + { + STempFlag = 1; + S = new CAMmatrixBase(); + S->initializeReturnArgument(*this); + *S = *this; + } + + if(A.Structure.isSubset() == 0) + { T = (CAMmatrixBase*)&A;} + else + { + TTempFlag = 1; + T = new CAMmatrixBase(); + T->initializeReturnArgument(A); + *T = A; + } +// +// return argument +// + long Rows = (*S).Structure[1].getIndexCount(); + long Cols = A.Structure[2].getIndexCount(); + + CAMrange R1( (*S).Structure[1].getIndexBase(), + (*S).Structure[1].getIndexBase() + Rows - 1); + + CAMrange R2(A.Structure[2].getIndexBase(), + A.Structure[2].getIndexBase() + Cols - 1); + + CAMmatrixBase R(CAMType::typeDouble,R1, R2); +// +// dgemm performs the operation R := alpha*op(S)*op(T) + beta*R; +// op(matrix) is either the matrix or its transpose. +// the characters transX below specify that S and T are 'n'ot +// to be transposed. +// +// R = m by n +// S = m by k +// T = k by n +// + char transa = 'n'; + char transb = 'n'; + + long m = R.Structure[1].getIndexCount(); + long n = R.Structure[2].getIndexCount(); + long k = (*S).Structure[2].getIndexCount(); + + double* s = (double*)((*S).getDataPointer()); + double* t = (double*)((*T).getDataPointer()); + double* r = (double*)( R.getDataPointer()); + + long lds = (*S).Structure[1].getIndexCount(); + long ldt = (*T).Structure[1].getIndexCount(); + long ldr = R.Structure[1].getIndexCount(); + + double alpha = 1.0; + double beta = 0.0; + + short f1 = 1; + short f2 = 1; + + dgemm_(&transa, &transb, &m, &n, &k, &alpha, s, &lds, t, &ldt, + &beta, r, &ldr,f1,f2); +// +// clean up +// + if(STempFlag == 1) delete S; + if(TTempFlag == 1) delete T; + + R.setTemporaryFlag(); + return R; +} + + + +CAMvectorBase CAMmatrixBase::operator*(const CAMvectorBase& A) const +{ + if(Structure.isMatrixOpConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// +// +// Prepare Operands +// + int STempFlag = 0; + int TTempFlag = 0; + + CAMmatrixBase* S; + CAMvectorBase* T; + + if(Structure.isSubset() == 0) + { S = (CAMmatrixBase*)this;} + else + { + STempFlag = 1; + S = new CAMmatrixBase(); + S->initializeReturnArgument(*this); + *S = *this; + } + + if(A.Structure.isSubset() == 0) + { T = (CAMvectorBase*)&A;} + else + { + TTempFlag = 1; + T = new CAMvectorBase(); + T->initializeReturnArgument(A); + *T = A; + } +// +// return argument +// + long Rows = (S->operator[](1)).getIndexCount(); + long Cols = A.Structure[2].getIndexCount(); + + CAMrange R1((S->operator[](1)).getIndexBase(), + (S->operator[](1)).getIndexBase() + Rows - 1); + + CAMrange R2(A.Structure[2].getIndexBase(), + A.Structure[2].getIndexBase() + Cols - 1); + + CAMvectorBase R; + if(R1.length() == 1) + {R.initialize(CAMType::typeDouble,R2);} + else + {R.initialize(CAMType::typeDouble,R1);} +// +// +// dgemm performs the operation R := alpha*op(S)*op(T) + beta*R; +// op(matrix) is either the matrix or its transpose. +// the characters transX below specify that S and T are 'n'ot +// to be transposed. +// +// R = m by n +// S = m by k +// T = k by n +// + char transa = 'n'; + char transb = 'n'; + + long m = R.Structure[1].getIndexCount(); + long n = R.Structure[2].getIndexCount(); + long k = (*S).Structure[2].getIndexCount(); + + double* s = (double*)((*S).getDataPointer()); + double* t = (double*)((*T).getDataPointer()); + double* r = (double*)( R.getDataPointer()); + + long lds = (*S).Structure[1].getIndexCount(); + long ldt = (*T).Structure[1].getIndexCount(); + long ldr = R.Structure[1].getIndexCount(); + + double alpha = 1.0; + double beta = 0.0; + + short f1 = 1; + short f2 = 1; + + dgemm_(&transa, &transb, &m, &n, &k, &alpha, s, &lds, t, &ldt, + &beta, r, &ldr,f1,f2); +// +// clean up +// + if(STempFlag == 1) delete S; + if(TTempFlag == 1) delete T; + + R.setTemporaryFlag(); + return R; +} +CAMmatrixBase CAMmatrixBase::operator/(const CAMmatrixBase& A) const +{ + if(Structure.isMatrixOpConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + + if(Structure[1].getIndexCount() != + Structure[2].getIndexCount()) + {CAMmatrixBase::nonSquareMessage();} +// +// NEED CONVERSION CHECK -- need to check for square left hand side +// +// +// Turned off equilibration in the / routine so that the input +// matrices and vectors are un-modified by the calculation. CRA 8/1/97 +// +// Prepare Operands +// + int STempFlag = 0; + int TTempFlag = 0; + + CAMmatrixBase* S; + CAMmatrixBase* T; + + if(Structure.isSubset() == 0) + { S = (CAMmatrixBase*)this;} + else + { + STempFlag = 1; + S = new CAMmatrixBase(); + S->initializeReturnArgument(*this); + *S = *this; + } + + if(A.Structure.isSubset() == 0) + { T = (CAMmatrixBase*)&A;} + else + { + TTempFlag = 1; + T = new CAMmatrixBase(); + T->initializeReturnArgument(A); + *T = A; + } +// +// return argument +// + long Rows = (*S).Structure[1].getIndexCount(); + long Cols = A.Structure[2].getIndexCount(); + + CAMrange R1((*S).Structure[1].getIndexBase(), + (*S).Structure[1].getIndexBase() + Rows - 1); + + CAMrange R2(A.Structure[2].getIndexBase(), + A.Structure[2].getIndexBase() + Cols - 1); + + CAMmatrixBase R(CAMType::typeDouble,R1, R2); +// +// S R = T +// S : N by N +// R : N by NRHS +// T : N by NRHS +// + + char FACT = 'N'; // Factor - no equilibration + char TRANS = 'N'; // No transpose + long N = Rows; // Rows of S, R, and T + long NRHS = Cols; // Columns of R and T + + double* s = (double*)((*S).getDataPointer()); + double* t = (double*)((*T).getDataPointer()); + double* r = (double*)( R.getDataPointer()); + + long LDS = N; // leading dimension of S + long LDT = N; // leading dimension of T + long LDR = N; // leading dimension of R + + + double* SF = new double[N*N]; // factored form of S + long LDSF = N; // leading dimension of SF + + long* IPIV = new long[N]; // pivot vector of dimension N + + char EQUED = 'N'; // equilibration flag + + double* RS = new double[N]; // row and column scale factors + double* C = new double[N]; // dimension = N + + + double* FERR = new double[NRHS]; // forward error estimates + double* BERR = new double[NRHS]; // backward error estimates + double* WORK = new double[4*N]; // double work array + long* IWORK = new long[N]; // integer work array + + double RCOND = 0; // estimate of reciprocal of + // condition number + + long INFO = 0; // output information + + short f1a = 1; + short f1b = 1; + short f1c = 1; + + dgesvx_(&FACT,&TRANS,&N,&NRHS,s,&LDS,SF,&LDSF,IPIV, + &EQUED,RS,C,t,&LDT,r,&LDR,&RCOND, FERR, BERR, WORK, + IWORK,&INFO, f1a, f1b, f1c); +// +// Error Checking +// + if(INFO != 0) + { + if(INFO <= N) + { + cerr << " Matrix Singular " << endl; + cerr << " LU Factorization Stopped at Step " << INFO << endl; + cerr << " No Solution Returned " << endl; + } + + if(INFO ==(N +1)) + { + cerr << " Matrix Singular or Badly Conditioned " << endl; + cerr << " Computed Solution May Be Inaccurate " << endl; + cerr << " Condition Number = " << 1.0/RCOND << endl; + } + } + +// +// clean-up +// + delete [] IWORK; + delete [] WORK; + delete [] BERR; + delete [] FERR; + delete [] C; + delete [] RS; + delete [] SF; + delete [] IPIV; + + if(STempFlag == 1) delete S; + if(TTempFlag == 1) delete T; + + R.setTemporaryFlag(); + return R; +} +CAMvectorBase CAMmatrixBase::operator/(const CAMvectorBase& A) const +{ + if(Structure.isMatrixOpConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + + if((this)->operator[](1).getIndexCount() != + (this)->operator[](1).getIndexCount()) + {CAMmatrixBase::nonSquareMessage();} +// +// NEED CONVERSION CHECK -- need to check for square left hand side +// +// Turned off equilibration in the / routine so that the input +// matrices and vectors are un-modified by the calculation. CRA 1/14/98 +// +// Prepare Operands +// + int STempFlag = 0; + int TTempFlag = 0; + + CAMmatrixBase* S; + CAMvectorBase* T; + + if(Structure.isSubset() == 0) // point to argument if not a submatrix + { S = (CAMmatrixBase*)this;} // + else // else + { + STempFlag = 1; // indicate making a temporary + S = new CAMmatrixBase(); // create a container + S->initializeReturnArgument(*this);// initialize with structure of the argument + *S = *this; // copy over contents + } + + if(A.Structure.isSubset() == 0) + { T = (CAMvectorBase*)&A;} + else + { + TTempFlag = 1; + T = new CAMvectorBase(); + T->initializeReturnArgument(A); + *T = A; + } +// +// return argument +// + long Rows = (S->operator[](1)).getIndexCount(); + long Cols = A.Structure[2].getIndexCount(); + + CAMrange R1((S->operator[](1)).getIndexBase(), + (S->operator[](1)).getIndexBase() + Rows - 1); + + CAMrange R2(A.Structure[2].getIndexBase(), + A.Structure[2].getIndexBase() + Cols - 1); + + CAMvectorBase R; + if(R1.length() == 1) + {R.initialize(CAMType::typeDouble,R2);} + else + {R.initialize(CAMType::typeDouble,R1);} +// +// S R = T +// S : N by N +// R : N by NRHS +// T : N by NRHS +// + + char FACT = 'N'; // No equilibrate, but factor + char TRANS = 'N'; // No transpose + long N = Rows; // Rows of S, R, and T + long NRHS = Cols; // Columns of R and T + + double* s = (double*)((*S).getDataPointer()); + double* t = (double*)((*T).getDataPointer()); + double* r = (double*)( R.getDataPointer()); + + long LDS = N; // leading dimension of S + long LDT = N; // leading dimension of T + long LDR = N; // leading dimension of R + + + double* SF = new double[N*N]; // factored form of S + long LDSF = N; // leading dimension of SF + + long* IPIV = new long[N]; // pivot vector of dimension N + + char EQUED = 'B'; // equilibration flag + + double* RS = new double[N]; // row and column scale factors + double* C = new double[N]; // dimension = N + + + double* FERR = new double[NRHS]; // forward error estimates + double* BERR = new double[NRHS]; // backward error estimates + double* WORK = new double[4*N]; // double work array + long* IWORK = new long[N]; // integer work array + + double RCOND = 0; // estimate of reciprocal of + // condition number + + long INFO = 0; // output information + + short f1a = 1; + short f1b = 1; + short f1c = 1; + + dgesvx_(&FACT,&TRANS,&N,&NRHS,s,&LDS,SF,&LDSF,IPIV, + &EQUED,RS,C,t,&LDT,r,&LDR,&RCOND, FERR, BERR, WORK, + IWORK,&INFO, f1a, f1b, f1c); +// +// Error Checking +// + if(INFO != 0) + { + if(INFO <= N) + { + cerr << " Matrix Singular " << endl; + cerr << " LU Factorization Stopped at Step " << INFO << endl; + cerr << " No Solution Returned " << endl; + } + + if(INFO ==(N +1)) + { + cerr << " Matrix Singular or Badly Conditioned " << endl; + cerr << " Computed Solution May Be Inaccurate " << endl; + cerr << " Condition Number = " << 1.0/RCOND << endl; + } + } + +// +// clean-up +// + delete [] IWORK; + delete [] WORK; + delete [] BERR; + delete [] FERR; + delete [] C; + delete [] RS; + delete [] SF; + delete [] IPIV; + + if(STempFlag == 1) delete S; + if(TTempFlag == 1) delete T; + + R.setTemporaryFlag(); + return R; +} +// +//***************************************************************** +// op = Operators +//***************************************************************** +// + +void CAMmatrixBase::operator+=(const CAMmatrixBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAplusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +// +//***************************************************************** +// op = Operators +//***************************************************************** +// + +void CAMmatrixBase::operator+=(const CAMvectorBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAplusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMmatrixBase::operator-=(const CAMmatrixBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAminusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMmatrixBase::operator-=(const CAMvectorBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAminusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMmatrixBase::operator*=(const CAMmatrixBase& A) +{ + if((Structure.isMatrixOpConformingTo(A.Structure) != 1)|| + (A.Structure.isMatrixOpConformingTo(Structure) != 1)) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + (*this) = (*this) * A; +} +void CAMmatrixBase::operator*=(const CAMvectorBase& A) +{ + if((Structure.isMatrixOpConformingTo(A.Structure) != 1)|| + (A.Structure.isMatrixOpConformingTo(Structure) != 1)) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + (*this) = (*this) * A; +} + +void CAMmatrixBase::operator/=(const CAMmatrixBase& A) +{ + if((Structure.isMatrixOpConformingTo(A.Structure) != 1)|| + (A.Structure.isMatrixOpConformingTo(Structure) != 1)) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + (*this) = (*this)/A; +} + +void CAMmatrixBase::operator/=(const CAMvectorBase& A) +{ + if((Structure.isMatrixOpConformingTo(A.Structure) != 1)|| + (A.Structure.isMatrixOpConformingTo(Structure) != 1)) + {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);} + (*this) = (*this)/A; +} + +CAMmatrixBase CAMmatrixBase::transpose() const +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(CAMType::typeDouble, + _(Structure[2].getIndexBase(),Structure[2].getIndexBound()), + _(Structure[1].getIndexBase(),Structure[1].getIndexBound())); + + CAMstructureBase ASubset(Structure); + CAMstructureBase BSubset(S.Structure); + + long i; + for(i = Structure[1].getIndexBase(); + i <= Structure[1].getIndexBound();i++) + { + ASubset.setStructureSubset(i,_); + BSubset.setStructureSubset(_,i); + CAMbinaryEngine::doubleAequalToB(BSubset, *S.DataP, ASubset, *DataP); + } + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMmatrixBase::operator~() const +{ +// Transpose Operator +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(CAMType::typeDouble, + _(Structure[2].getIndexBase(),Structure[2].getIndexBound()), + _(Structure[1].getIndexBase(),Structure[1].getIndexBound())); + + CAMstructureBase ASubset(Structure); + CAMstructureBase BSubset(S.Structure); + + long i; + for(i = Structure[1].getIndexBase(); + i <= Structure[1].getIndexBound();i++) + { + ASubset.setStructureSubset(i,_); + BSubset.setStructureSubset(_,i); + CAMbinaryEngine::doubleAequalToB(BSubset, *S.DataP, ASubset, *DataP); + } + S.setTemporaryFlag(); + return S; +} +// +//***************************************************************** +// Operations with Scalers +//***************************************************************** +// +CAMmatrixBase CAMmatrixBase::operator +(const double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,AStructure);} + + CAMmatrixBase S(*this); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} +CAMmatrixBase operator +(const double value, const CAMmatrixBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase BStructure(_(1,1)); + if(A.Structure.isStrictConformingTo(BStructure) != 1) + {CAMmatrixBase::nonConformingMessage(A.Structure,BStructure);} + + CAMmatrixBase S(A); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMmatrixBase::operator -(const double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,AStructure);} + + CAMmatrixBase S(*this); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase operator -(const double value, const CAMmatrixBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase BStructure(_(1,1)); + if(A.Structure.isStrictConformingTo(BStructure) != 1) + {CAMmatrixBase::nonConformingMessage(A.Structure,BStructure);} + + CAMmatrixBase S(A); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +void CAMmatrixBase::operator +=(const double value) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,AStructure);} + + CAMbinaryEngine::doubleAplusEqualAlpha(Structure, *(DataP), value); +} + +void CAMmatrixBase::operator -=(const double value) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMmatrixBase::nonConformingMessage(Structure,AStructure);} + + CAMbinaryEngine::doubleAminusEqualAlpha(Structure, *(DataP), value); +} + +CAMmatrixBase CAMmatrixBase::operator*(double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(*this); + CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase operator *(double value, const CAMmatrixBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(A); + CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMmatrixBase::operator /(double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(*this); + CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase operator /(double value, const CAMmatrixBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(A); + CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +void CAMmatrixBase::operator *=(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMbinaryEngine::doubleAtimesEqualAlpha(Structure, *DataP, value); +} + +void CAMmatrixBase::operator /=(double value) +{ + CAMbinaryEngine::doubleAdivideEqualAlpha(Structure, *DataP, value); +} + + + +void CAMmatrixBase::setToValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value); +} + +CAMmatrixBase CAMmatrixBase::plusValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(*this); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMmatrixBase::minusValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S(*this); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +// +//***************************************************************** +// Temporary and Reference Utilities +//***************************************************************** +// +void CAMmatrixBase::exchangeContentsWith(CAMmatrixBase& B) +{ +// +// This routine exchanges the contents of *this with B. +// The routine is typically used with *this input as +// a null object and B a temporary object (i.e. the result +// of an operator or function which returns B with the +// temporary flag set). In such a case, the contents of +// B are captured by *this --- resulting in a transfer of the +// results without invoking a data copy. +// +// + CAMstructureBase S_temp(Structure); + CAMdataHandler* DataP_temp = DataP; + int typeValue_temp = typeValue; + int referenceFlag_temp = referenceFlag; + long matrixBaseReferenceCount_temp = matrixBaseReferenceCount; + + Structure.initialize(B.Structure); + DataP = B.DataP; + typeValue = B.typeValue; + referenceFlag = B.referenceFlag; + matrixBaseReferenceCount = B.matrixBaseReferenceCount; +// + B.Structure.initialize(S_temp); + B.DataP = DataP_temp; + B.typeValue = typeValue_temp; + B.referenceFlag = referenceFlag_temp; + B.matrixBaseReferenceCount = matrixBaseReferenceCount_temp; +} + +void CAMmatrixBase::initializeReferenceDuplicate(const CAMmatrixBase& B) +{ +// +// This routine initializes *this with the contents of B and +// and sets the *this reference flag. This results in a +// class instance whose data is that associated with B. +// +// Typically this routine is used in a container class which +// contains arrays --- and one wants to have sub-array access +// for the contained class which is based upon the sub-array +// access of the array class. +// + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + Structure.initialize(B.Structure); + DataP = B.DataP; + DataP->incrementReferenceCount(); //One Reference for local copy + DataP->incrementReferenceCount(); //One Reference for compiler copy + typeValue = B.typeValue; + referenceFlag = 1; + matrixBaseReferenceCount = 0; +} +// +//***************************************************************** +// CONVERSIONS +//***************************************************************** +// +CAMarrayBase CAMmatrixBase::asArray() const +{ + CAMarrayBase S; + if(DataP == 0) return S; + + CAMrange R1(Structure[1].getIndexBase(),Structure[1].getIndexBound()); + CAMrange R2(Structure[2].getIndexBase(),Structure[2].getIndexBound()); +// +// + S.initialize(CAMType::typeDouble, R1,R2); + CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP); +// +// + S.setTemporaryFlag(); + return S; +} +CAMvectorBase CAMmatrixBase::asVector() const +{ + CAMvectorBase S; + if(DataP == 0) return S; + + CAMrange R1; + long i; + long dimension = 0; + + for(i = 1; i <= getDimension(); i++) + { + if(Structure[i].getIndexCount() != 1) + { + dimension++; + if(dimension == 1) + R1.initialize(Structure[i].getIndexBase(),Structure[i].getIndexBound()); + } + } + switch (dimension) + { + case 0 : + R1.initialize(Structure[1].getIndexBase(),Structure[1].getIndexBound()); + break; + + case 1 : + break; + default : + CAMmatrixBase::objectConversionError(Structure); + + } +// +// + S.initialize(CAMType::typeDouble, R1); + CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP); +// +// + S.setTemporaryFlag(); + return S; +} +// +//***************************************************************** +// DIMENSION SELECTION +//***************************************************************** +// +CAMstructureBase& CAMmatrixBase::operator[](long i) +{ + if((i < 0)||(i > Structure.dataDimension)) + {CAMstructureBase::illegalDimension(i, Structure.dataDimension);} + + Structure.exchangeReferenceIndex(i); + + return Structure; +} + +const CAMstructureBase& CAMmatrixBase::operator[](long i) const +{ + if((i < 0)||(i > Structure.dataDimension)) + {CAMstructureBase::illegalDimension(i, Structure.dataDimension);} + + Structure.exchangeReferenceIndex(i); + + return Structure; +} + +void* CAMmatrixBase::getDataPointer(long i1, long i2) const +{ + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); +// +// NEED CONVERSION CHECK +// + double* dataPtr = (double*)(DataP->dataPointer); + + long offset; + offset = (i1 - *(beginPtr)) + + ((*(endPtr) - *(beginPtr)) + 1)*(i2 - *(beginPtr + 1)); + + + return (void*)(dataPtr + offset); +} +// +//******************************************************************************** +// Reference Counting Functions +//******************************************************************************** +// + +void CAMmatrixBase::incrementReferenceCount() +{ + if(matrixBaseReferenceCount == 0) CAMmatrixBase::referenceCountError(); + matrixBaseReferenceCount++; +} + +void CAMmatrixBase::referenceCountError() +{ +cerr << " Cannot Use Reference Counting on Objects New\'d by the Compiler " << endl; +CAMmvaExit(); +} +// +//***************************************************************** +// MEMBER_FUNCTIONS +//***************************************************************** +// + + +void CAMmatrixBase::indexCheck(const CAMstructureBase &S, long i1, long i2) +{ + if(S.dataDimension != 2) + { + cerr << " Error : Incorrect Matrix Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 2 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMmatrixBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMmatrixBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } +} + + + + + +void CAMmatrixBase::indexErrorMessage(long indexDimension, long base, long bound, long index) +{ + cerr << " Error : Index " << indexDimension << " Out of Range " << endl; + + cerr << " Current Index Range :(" << base << ", " << bound << ")" << endl; + cerr << " Index Used : " << index << endl; + CAMmvaExit(); +} +void CAMmatrixBase::nonConformingMessage(const CAMstructureBase& A, const CAMstructureBase& B) +{ + long i; + cerr << endl; + cerr << "Error : Object Dimensions not Compatable with Operation " << endl << endl; + cerr << "Left Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + cerr << "Right Operand Dimensions : "; + cerr << B[1].getIndexCount(); + for(i = 2; i <= B.dataDimension; i++) + cerr << " x " << B[i].getIndexCount(); + cerr << endl << endl; + CAMmvaExit(); +} +void CAMmatrixBase::doubleConversionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << "Dimensions not Compatable with Conversion to Double " << endl << endl; + cerr << "Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} + +void CAMmatrixBase::nonSquareMessage() +{ + cerr << endl; + cerr << "Matrix is not square : dimensions incompatable with matrix solve " << endl << endl; + CAMmvaExit(); +} + +void CAMmatrixBase::objectConversionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << " Dimensions not Compatable with Conversion Operator " << endl << endl; + cerr << "Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +void CAMmatrixBase::nullOperandError() +{ + cerr << endl; + cerr << " Error : Null Object Used As Operand " << endl; + CAMmvaExit(); +} +void CAMmatrixBase::nullOperandError(char* Operation) +{ + cerr << endl; + cerr << " Error : Null Object Used As Operand With "<< Operation << endl; + CAMmvaExit(); +} +void CAMmatrixBase::inputSizeError() +{ + cerr << endl; + cerr << " Input error : Insufficient # of data elements in input stream " << endl; + CAMmvaExit(); +} +// +//***************************************************************** +// CPP File End +//***************************************************************** +// + + + + + + + + + + + diff --git a/src/matrix/matbse.h b/src/matrix/matbse.h new file mode 100755 index 0000000..0be8561 --- /dev/null +++ b/src/matrix/matbse.h @@ -0,0 +1,208 @@ +// +//****************************************************************************** +// MATBSE.H +//****************************************************************************** +// + +#include +#include +#include "strctbse.h" +#include "datahndl.h" +#include "access.h" +#include "mvaexit.h" +#include "camtype.h" +#include "typehndl.h" + +// +// +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Tue Apr 16 11:30:42 1996 +// +//******************************************************************************** +// +#ifndef __NO_COMPLEX__ +#define __NO_COMPLEX__ +#endif +// +// +#include "mvaimpexp.h" // C +// +// +#ifndef _CAMARRAYBASE_ +class CAMarrayBase; +#endif +#ifndef _CAMVECTORBASE_ +class CAMvectorBase; +#endif +// +// +// + +#ifndef _CAMMATRIXBASE_ +#define _CAMMATRIXBASE_ + + +class __IMPEXP__ CAMmatrixBase +{ + +public : + + CAMstructureBase Structure; + CAMdataHandler* DataP; + int typeValue; + int referenceFlag; + long matrixBaseReferenceCount; + +public : + + friend class CAMvectorBase; + +// +// Constructors +// + CAMmatrixBase(); + CAMmatrixBase( const CAMmatrixBase& A); + CAMmatrixBase(int d_type); + CAMmatrixBase(int d_type, const CAMrange& R1, const CAMrange& R2); +// +// Destructor +// + ~CAMmatrixBase(); +// +// Assignment +// + void operator = (double value); + void operator = (const CAMmatrixBase& A); + void operator = (const CAMvectorBase& A); +// +// Output +// + __IMPEXP__ friend ostream& operator <<(ostream& out_stream, const CAMmatrixBase& A); +// +// Input +// + __IMPEXP__ friend istream& operator >>(istream& in_stream, CAMmatrixBase& A); +// +// Initialization Functions +// + void initialize(); + void initialize(const CAMmatrixBase& A); + void initialize(int d_type); + void initialize(int d_type, const CAMrange& R1, const CAMrange& R2); +// +// Unary and Binary Operations +// + CAMmatrixBase operator-() const; + CAMmatrixBase operator+(const CAMmatrixBase& A) const; + CAMmatrixBase operator+(const CAMvectorBase& A) const; + CAMmatrixBase operator-(const CAMmatrixBase& A) const; + CAMmatrixBase operator-(const CAMvectorBase& A) const; + CAMmatrixBase operator*(const CAMmatrixBase& A) const; + CAMvectorBase operator*(const CAMvectorBase& A) const; + CAMmatrixBase operator/(const CAMmatrixBase& A) const; + CAMvectorBase operator/(const CAMvectorBase& A) const; + void operator+=(const CAMmatrixBase& A); + void operator+=(const CAMvectorBase& A); + void operator-=(const CAMmatrixBase& A); + void operator-=(const CAMvectorBase& A); + void operator*=(const CAMmatrixBase& A); + void operator*=(const CAMvectorBase& A); + void operator/=(const CAMmatrixBase& A); + void operator/=(const CAMvectorBase& A); + CAMmatrixBase transpose() const; + CAMmatrixBase operator~() const; +// +// Scaler Operations +// + CAMmatrixBase operator +(const double value) const; + __IMPEXP__ friend CAMmatrixBase operator +(const double value, const CAMmatrixBase& A); + CAMmatrixBase operator -(const double value) const; + __IMPEXP__ friend CAMmatrixBase operator -(const double value, const CAMmatrixBase& A); + void operator +=(const double value); + void operator -=(const double value); + CAMmatrixBase operator *(double value) const; + __IMPEXP__ friend CAMmatrixBase operator *(double value, const CAMmatrixBase& A); + CAMmatrixBase operator /(double value) const; + __IMPEXP__ friend CAMmatrixBase operator /(double value, const CAMmatrixBase& A); + void operator *=(double value); + void operator /=(double value); +// +// Additional Scalar Functions +// + void setToValue(double value); + CAMmatrixBase plusValue(double value); + CAMmatrixBase minusValue(double value); +// +// Helper Functions +// + void setTemporaryFlag(){DataP->setTemporaryFlag();}; + void initializeReturnArgument(const CAMstructureBase& S, int dataT); + void initializeReturnArgument(const CAMmatrixBase& A); + void initializeMinDuplicate(const CAMmatrixBase& A); + void* getDataPointer() const {return DataP->getDataPointer();}; + void* getDataPointer(long i1, long i2) const; + CAMarrayBase asArray() const; + CAMvectorBase asVector() const; +// +// Structure Functions +// + const CAMstructureBase& operator[](long i) const; + CAMstructureBase& operator[](long i); + void setAllIndexBase(long i){Structure.setAllIndexBase(i);}; + long getDimension() const {return Structure.getDimension();}; +// +// Reference Counting +// + void incrementReferenceCount(); + void decrementReferenceCount(){matrixBaseReferenceCount--;}; + int getReferenceCount() const {return matrixBaseReferenceCount;}; + void setReferenceCount(int refValue){matrixBaseReferenceCount = refValue;}; + static void referenceCountError(); +// +// Error Handling Routines +// + static void indexCheck(const CAMstructureBase &S, long i1, long i2); + static void indexErrorMessage(long indexDimension, long base, long bound, long index); + static void nonConformingMessage(const CAMstructureBase &A,const CAMstructureBase &B); + static void doubleConversionError(const CAMstructureBase& A); + static void nonSquareMessage(); + static void objectConversionError(const CAMstructureBase& A); + static void nullOperandError(); + static void nullOperandError(char* Operation); + static void inputSizeError(); +// +// Utility Functions +// + double max() const; + double min() const; + double maxAbs() const; + double minAbs() const; + double infNorm() const; + double pNorm(int p) const; + double pNorm(long p) const; + double pNorm(float p) const; + double pNorm(double p) const; +// +// Matrix Specific Utility Routines +// + CAMmatrixBase inverse() const; +// +// temporary and reference utility functions +// + void exchangeContentsWith(CAMmatrixBase& B); + void initializeReferenceDuplicate(const CAMmatrixBase& B); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + diff --git a/src/matrix/matgph.cpp b/src/matrix/matgph.cpp new file mode 100755 index 0000000..181c9b0 --- /dev/null +++ b/src/matrix/matgph.cpp @@ -0,0 +1,529 @@ +#include "matbse.h" +// +//****************************************************************************** +// MATGPH.CPP +//****************************************************************************** +// +// BINDINGS TO THE UC GRAHPICS CLASSES +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Tue Sep 26 14:40:00 1995 +// +//******************************************************************************** +// + +void CAMmatrixBase::plot() const +{ +// +// Need Conversion Check +// + long dimension; + long M,N; + + const CAMmatrixBase* InputPtr; + CAMmatrixBase A; + + double* AdataPtr; double* BdataPtr; + + long j; int autoFlag; + double x_min, x_max, y_min, y_max; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + InputPtr = &A; + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + InputPtr = this; + } + + switch (dimension) + { + case 1 : + CAMgraphics::plot(AdataPtr,M); + + break; + + case 2 : + autoFlag = CAMgraphics::getAutoScaleFlag(); + x_min = 1; + x_max = M; + y_min = InputPtr->min(); + y_max = InputPtr->max(); + CAMgraphics::axis(x_min,x_max,y_min,y_max); + for(j = 1; j <= N; j++) + { + BdataPtr = AdataPtr + (j-1)*M; + CAMgraphics::plot(BdataPtr,M); + } + CAMgraphics::axis(autoFlag); + + break; + default : + CAMmatrixBase::plotDimensionError(A.Structure); + } + +} + +void CAMmatrixBase::plot(int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + if(p_arg < 32) + { CAMgraphics::setPlotStyle(p_arg);} + else + { CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(CAMgraphics::POINTS); + } + + this->plot(); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} +void CAMmatrixBase::plot(int p_style, int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(p_style); + + this->plot(); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} +void CAMmatrixBase::plot(const CAMmatrixBase& Ordinates) const +{ +// +// Need Conversion Check +// + long dimension; + long M,N; + + CAMmatrixBase A; + const CAMmatrixBase* InputPtr; + double* AdataPtr; double* BdataPtr; + + long j; int autoFlag; + double x_min, x_max, y_min, y_max; + + CAMmatrixBase O; + double* OdataPtr; + long Odimension; + long Ocount; +// + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + InputPtr = &A; + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + InputPtr = this; + } + + if(Ordinates.Structure.isSubset() == 1) + { + O.initializeMinDuplicate(Ordinates); + Odimension = O.getDimension(); + OdataPtr = (double*)O.getDataPointer(); + Ocount = O[1].getIndexCount(); + } + else + { + Odimension = Ordinates.getDimension(); + OdataPtr = (double*)Ordinates.getDataPointer(); + Ocount = Ordinates[1].getIndexCount(); + } + + if(Odimension != 1) + {CAMmatrixBase::ordinateError(Ordinates.Structure);} + + if(M != Ocount) + {CAMmatrixBase::ordinateError(Ordinates.Structure);} + + switch (dimension) + { + case 1 : + CAMgraphics::plot(OdataPtr,AdataPtr,M); + + break; + + case 2 : + + autoFlag = CAMgraphics::getAutoScaleFlag(); + x_min = *OdataPtr; + x_max = *(OdataPtr +(M-1)); + y_min = InputPtr->min(); + y_max = InputPtr->max(); + CAMgraphics::axis(x_min,x_max,y_min,y_max); + for(j = 1; j <= N; j++) + { + BdataPtr = AdataPtr + (j-1)*M; + CAMgraphics::plot(OdataPtr, BdataPtr,M); + } + CAMgraphics::axis(autoFlag); + + break; + default : + CAMmatrixBase::plotDimensionError(A.Structure); + } + +} + +void CAMmatrixBase::plot(const CAMmatrixBase& Ordinates, int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + if(p_arg < 32) + { CAMgraphics::setPlotStyle(p_arg);} + else + { CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(CAMgraphics::POINTS); + } + + this->plot(Ordinates); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} + +void CAMmatrixBase::plot(const CAMmatrixBase& Ordinates, int p_arg, int p_style) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(p_style); + + this->plot(Ordinates); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} + +void CAMmatrixBase::contour() const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::contour(AdataPtr,M,N); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMmatrixBase::plotDimensionError(A.Structure);} + +} + +void CAMmatrixBase::contour(int nContour) const +{ + CAMgraphics::setContourLevel(nContour); + this->contour(); +} + +void CAMmatrixBase::contour(long nContour) const +{ + CAMgraphics::setContourLevel(nContour); + this->contour(); +} +void CAMmatrixBase::contour(double increment) const +{ + CAMgraphics::setContourLevel(increment); + this->contour(); +} + +void CAMmatrixBase::contour(double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(low_value, high_value); + this->contour(); +} + +void CAMmatrixBase::contour(long nContour, double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(nContour, low_value, high_value); + this->contour(); +} + +void CAMmatrixBase::contour(int nContour, double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(nContour, low_value, high_value); + this->contour(); +} + +void CAMmatrixBase::contour(double increment, double low_value, double high_value) const +{ + CAMgraphics::setContourLevel(increment, low_value, high_value); + this->contour(); +} + +void CAMmatrixBase::contour(const CAMmatrixBase& contourValues) const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + CAMmatrixBase CV; + double* CVdataPtr; + long CVdimension; + long CVcount; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(contourValues.Structure.isSubset() == 1) + { + CV.initializeMinDuplicate(contourValues); + CVdimension = CV.getDimension(); + CVdataPtr = (double*)CV.getDataPointer(); + CVcount = CV[1].getIndexCount(); + } + else + { + CVdimension = contourValues.getDimension(); + CVdataPtr = (double*)contourValues.getDataPointer(); + CVcount = contourValues[1].getIndexCount(); + } + + + if(CVdimension != 1) + {CAMmatrixBase::ordinateError(contourValues.Structure);} + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::contour(AdataPtr,M,N,CVdataPtr,CVcount); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMmatrixBase::plotDimensionError(A.Structure);} + +} + +void CAMmatrixBase::surface() const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::surface(AdataPtr,M,N); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMmatrixBase::plotDimensionError(A.Structure);} +} + +void CAMmatrixBase::surface(const CAMmatrixBase& x, const CAMmatrixBase& y) const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataPtr; + + long dimension; + long M,N; + int Fflag; + + CAMmatrixBase XC; + double* XCdataPtr; + long XCdimension; + long XCcount; + + CAMmatrixBase YC; + double* YCdataPtr; + long YCdimension; + long YCcount; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension >= 1) M = A[1].getIndexCount(); + if(dimension == 2) N = A[2].getIndexCount(); + } + else + { + dimension = getDimension(); + AdataPtr = (double*)getDataPointer(); + if(dimension >= 1) M = Structure[1].getIndexCount(); + if(dimension == 2) N = Structure[2].getIndexCount(); + } + + if(x.Structure.isSubset() == 1) + { + XC.initializeMinDuplicate(x); + XCdimension = x.getDimension(); + XCdataPtr = (double*)x.getDataPointer(); + XCcount = x[1].getIndexCount(); + } + else + { + XCdimension = x.getDimension(); + XCdataPtr = (double*)x.getDataPointer(); + XCcount = x[1].getIndexCount(); + } + + if(y.Structure.isSubset() == 1) + { + YC.initializeMinDuplicate(y); + YCdimension = y.getDimension(); + YCdataPtr = (double*)y.getDataPointer(); + YCcount = y[1].getIndexCount(); + } + else + { + YCdimension = y.getDimension(); + YCdataPtr = (double*)y.getDataPointer(); + YCcount = y[1].getIndexCount(); + } + + if(XCdimension != 1) + {CAMmatrixBase::ordinateError(x.Structure);} + + if(YCdimension != 1) + {CAMmatrixBase::ordinateError(y.Structure);} + + if(M != XCcount) + {CAMmatrixBase::ordinateError(x.Structure);} + + if(N != YCcount) + {CAMmatrixBase::ordinateError(y.Structure);} + + + if(dimension == 2) + { + Fflag = CAMgraphics::getFortranArrayFlag(); + CAMgraphics::fortranArrayFlagOn(); + CAMgraphics::surface(AdataPtr,M, N, XCdataPtr, YCdataPtr); + if(Fflag == 0) CAMgraphics::fortranArrayFlagOff(); + } + else + {CAMmatrixBase::plotDimensionError(A.Structure);} + +} + +void CAMmatrixBase::ordinateError(const CAMstructureBase & A) +{ + long i; + cerr << endl; + cerr << " Ordinates in Plot Command Incorrectly Specified " << endl << endl; + cerr << " Error in Number of Ordinates or Ordinate Array Dimension " << endl; + cerr << " Ordinates Size : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +void CAMmatrixBase::plotDimensionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << "Error : Object Dimensions not Compatable with Plot Operation " << endl << endl; + cerr << " Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// diff --git a/src/matrix/matrix.pro b/src/matrix/matrix.pro new file mode 100644 index 0000000..3fd4d8f --- /dev/null +++ b/src/matrix/matrix.pro @@ -0,0 +1,38 @@ +# +# $Id: matrix.pro,v 1.3 2003/12/05 15:43:30 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = *.h camblas/*.h camlapack/*.h +SOURCES = arraybse.cpp\ + arrayutl.cpp\ + datahndl.cpp\ + dbengnea.cpp\ + dbengneb.cpp\ + dmatrix.cpp\ + matbse.cpp\ + matutl.cpp\ + mvaexit.cpp\ + mvalngbase.cpp\ + range.cpp\ + strctbse.cpp\ + under.cpp\ + vecbse.cpp\ + vecutl.cpp \ + camblas/*.c camblas/*.cpp \ + camlapack/*.c + +TARGET = osessame_matrix +VERSION = 1.0 +DESTDIR = ../../lib/ +INCLUDEPATH = camblas/ camlapack/ +CONFIG = console staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = diff --git a/src/matrix/matutl.cpp b/src/matrix/matutl.cpp new file mode 100755 index 0000000..f4bd18e --- /dev/null +++ b/src/matrix/matutl.cpp @@ -0,0 +1,192 @@ +#include "dmatrix.h" +#include "bnengine.h" +// +//******************************************************************************** +// UTILITY MEMBER_FUNCTIONS +//******************************************************************************** +// +// +// Routines return double. When adding multiple data types, I'll +// need to promote the utilities to the derived classes so that +// they can return the appropriate type. +// +double CAMmatrixBase::max() const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxValue(AdataP, n, value); + return value; +} + +double CAMmatrixBase::min() const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMinValue(AdataP, n, value); + return value; +} + +double CAMmatrixBase::maxAbs() const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxAbsValue(AdataP, n, value); + return value; +} + +double CAMmatrixBase::minAbs() const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMinAbsValue(AdataP, n, value); + return value; +} + + +double CAMmatrixBase::infNorm() const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxAbsValue(AdataP, n, value); + return value; +} + +double CAMmatrixBase::pNorm(double p) const +{ +// +// Need Conversion Check +// + CAMmatrixBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doublepNorm(AdataP, n, p, value); + return value; +} + +double CAMmatrixBase::pNorm(int p) const {return pNorm(double(p));} +double CAMmatrixBase::pNorm(long p) const {return pNorm(double(p));} +double CAMmatrixBase::pNorm(float p) const {return pNorm(double(p));} + +// +// These routines are being put in the base type for now +// + +CAMmatrixBase CAMmatrixBase::inverse() const +{ + long m = (*this)[1].getIndexCount(); + long n = (*this)[2].getIndexCount(); + CAMdoubleMatrix I = CAMdoubleMatrix::identity(n); + return (*this)/I; +} + +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + + diff --git a/src/matrix/mvaexit.cpp b/src/matrix/mvaexit.cpp new file mode 100755 index 0000000..a345894 --- /dev/null +++ b/src/matrix/mvaexit.cpp @@ -0,0 +1,64 @@ +//****************************************************************************** +// MVAEXIT.CPP +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1997 +// 7/31/97 +// +// +//******************************************************************************** +// +#include "mvaexit.h" +#include "string.h" +#include "stdlib.h" +#include "stdio.h" +#include "iostream.h" +#ifndef __BCPLUSPLUS__ +void CAMmvaExit() +{ + cerr << " Fatal Error : Program Stopped " << endl; + exit(1); +}; +void CAMmvaExit(char* ErrorMessage) +{ + cerr << ErrorMessage << endl << endl << endl; + cerr << " Fatal Error " << endl; + exit(1); +}; +#else +void CAMmvaExit() +{ + cerr << endl << endl; + cerr << "Hit return to Exit " << endl << endl; + getchar(); + throw CAMmvaException("Error In CAM mvametric entity Classes"); +}; +void CAMmvaExit(char* ErrorMessage) +{ + throw CAMmvaException(ErrorMessage); +}; +CAMmvaException::CAMmvaException() +{ + errorMessage = new char[1]; + errorMessage[0] = '\0'; +} +CAMmvaException::CAMmvaException(char* Emessage) +{ + errorMessage = new char[strlen(Emessage) + 1]; + strcpy(errorMessage, Emessage); +} +CAMmvaException::CAMmvaException(const CAMmvaException& C) +{ + errorMessage = new char[strlen(C.errorMessage) + 1]; + strcpy(errorMessage, C.errorMessage); +} +CAMmvaException::~CAMmvaException() +{ + delete [] errorMessage; +} +#endif + + diff --git a/src/matrix/mvaexit.h b/src/matrix/mvaexit.h new file mode 100755 index 0000000..9646a83 --- /dev/null +++ b/src/matrix/mvaexit.h @@ -0,0 +1,42 @@ +//****************************************************************************** +// MVAEXIT.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1997 +// 7/30/97 +// +// +//******************************************************************************** +// +#ifndef __CAMMVAEXIT__ +#define __CAMMVAEXIT__ + +#include "mvaimpexp.h" + +void __IMPEXP__ CAMmvaExit(); +void __IMPEXP__ CAMmvaExit(char* ErrorMessage); + +#ifdef __BCPLUSPLUS__ + +class __IMPEXP__ CAMmvaException +{ + public : + + CAMmvaException(); + CAMmvaException(const CAMmvaException& C); + CAMmvaException(char* msg); + ~CAMmvaException(); + + char* getMessage() const {return errorMessage;}; + + private : + + char* errorMessage; +}; +#endif +#endif + + diff --git a/src/matrix/mvagph.cpp b/src/matrix/mvagph.cpp new file mode 100755 index 0000000..0f4f1d2 --- /dev/null +++ b/src/matrix/mvagph.cpp @@ -0,0 +1,1155 @@ +// +//****************************************************************************** +// MVAGPH.CPP +//****************************************************************************** +// +#include "mvagph.h" +#include "math.h" +#include "string.h" +#define CAM_PI 3.14159265359 +// +//****************************************************************************** +// +// Chris Anderson (C) UCLA 1997 +// 8/1/97 +// +// ->Fixed transposed problem 1/2/98 CRA +//****************************************************************************** +// +CAMmvaGraphics::CAMmvaGraphics() : CAMgraphicsProcess() {} +// +//****************************************************************************** +//****************************************************************************** +// Graphics Bindings for CAMvectorBase +//****************************************************************************** +//****************************************************************************** +// +void CAMmvaGraphics::plot(const CAMvectorBase& V) +{ + int p_arg = 0; + int p_style = 0; + int callType = 0; + vectorBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMvectorBase& V, int p_arg) +{ + int p_style = 0; + int callType = 1; + vectorBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMvectorBase& V, int p_arg, int p_style) +{ + int callType = 2; + vectorBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::vectorBasePlot(const CAMvectorBase& V, int callType, int p_arg, int p_style) +{ +// +// Need Conversion Check +// +// +// extract data from vector +// + long M; + CAMvectorBase A; + double* AdataPtr; + + if(V.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(V); + AdataPtr = (double*)A.getDataPointer(); + M = A.getIndexCount(); + } + else + { + AdataPtr = (double*)(V.getDataPointer()); + M = V.getIndexCount(); + } +// +// get reference to the graphics base class +// + CAMgraphicsProcess& G = *this; +// +// plot +// + switch(callType) + { + case 0 : G.plot(AdataPtr,M); break; + case 1 : G.plot(AdataPtr,M,p_arg); break; + case 2 : G.plot(AdataPtr,M,p_arg,p_style); break; + } +} + +void CAMmvaGraphics::plot(const CAMvectorBase& Vx, const CAMvectorBase& Vy) +{ + int p_arg = 0; + int p_style = 0; + int callType = 0; + vectorBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMvectorBase& Vx, const CAMvectorBase& Vy, int p_arg) +{ + int p_style = 0; + int callType = 1; + vectorBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMvectorBase& Vx, const CAMvectorBase& Vy, int p_arg, int p_style) +{ + int callType = 2; + vectorBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::vectorBasePlot(const CAMvectorBase& Vx, const CAMvectorBase& Vy, +int callType, int p_arg, int p_style) +{ +// +// Need Conversion Check +// + long M; + + CAMvectorBase A; + double* AdataPtr; + + CAMvectorBase O; + double* OdataPtr; + long Ocount; + + if(Vx.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(Vx); + AdataPtr = (double*)A.getDataPointer(); + M = A.getIndexCount(); + } + else + { + AdataPtr = (double*)Vx.getDataPointer(); + M = Vx.getIndexCount(); + } + + if(Vy.Structure.isSubset() == 1) + { + O.initializeMinDuplicate(Vy); + OdataPtr = (double*)O.getDataPointer(); + Ocount = O.getIndexCount(); + } + else + { + OdataPtr = (double*)Vy.getDataPointer(); + Ocount = Vy.getIndexCount(); + } + + if(M != Ocount) + {CAMmvaGraphics::ordinateError(Vy.Structure);} +// +// get reference to the graphics base class +// + CAMgraphicsProcess& G = *this; +// +// plot +// + switch(callType) + { + case 0 : G.plot(AdataPtr,OdataPtr,M); break; + case 1 : G.plot(AdataPtr,OdataPtr,M,p_arg); break; + case 2 : G.plot(AdataPtr,OdataPtr,M,p_arg,p_style); break; + } + +} + +// +//****************************************************************************** +//****************************************************************************** +// Graphics Bindings for CAMarrayBase +//****************************************************************************** +//****************************************************************************** +// + +// +//****************************************************************************** +//****************************************************************************** +// PLOT +//****************************************************************************** +//****************************************************************************** +// + +void CAMmvaGraphics::plot(const CAMarrayBase& V) +{ + int p_arg = 0; + int p_style = 0; + int callType = 0; + arrayBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMarrayBase& V, int p_arg) +{ + int p_style = 0; + int callType = 1; + arrayBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMarrayBase& V, int p_arg, int p_style) +{ + int callType = 2; + arrayBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::arrayBasePlot(const CAMarrayBase& V, int callType, +int p_arg, int p_style) +{ +// +// Need Conversion Check +// +// +// extract data from vector +// + long M; + CAMarrayBase A; + double* AdataPtr; + + long dimension; + + if(V.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(V); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + M = A[1].getIndexCount(); + } + else + { + dimension = V.getDimension(); + AdataPtr = (double*)(V.getDataPointer()); + M = V[1].getIndexCount(); + } + + if(dimension != 1) return; +// +// get reference to the graphics base class +// + CAMgraphicsProcess& G = *this; +// +// plot +// + switch(callType) + { + case 0 : G.plot(AdataPtr,M); break; + case 1 : G.plot(AdataPtr,M,p_arg); break; + case 2 : G.plot(AdataPtr,M,p_arg,p_style); break; + } +} + +void CAMmvaGraphics::plot(const CAMarrayBase& Vx, const CAMarrayBase& Vy) +{ + int p_arg = 0; + int p_style = 0; + int callType = 0; + arrayBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMarrayBase& Vx, const CAMarrayBase& Vy, +int p_arg) +{ + int p_style = 0; + int callType = 1; + arrayBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMarrayBase& Vx, const CAMarrayBase& Vy, +int p_arg, int p_style) +{ + int callType = 2; + arrayBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::arrayBasePlot(const CAMarrayBase& Vx, const CAMarrayBase& Vy, +int callType, int p_arg, int p_style) +{ +// +// Need Conversion Check +// + long dimensionX; + long dimensionY; + + long M; + + CAMarrayBase A; + double* AdataPtr; + + CAMarrayBase O; + double* OdataPtr; + long Ocount; + + if(Vx.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(Vx); + dimensionX = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + M = A[1].getIndexCount(); + } + else + { + dimensionX = Vx.getDimension(); + AdataPtr = (double*)Vx.getDataPointer(); + M = Vx[1].getIndexCount(); + } + + if(Vy.Structure.isSubset() == 1) + { + O.initializeMinDuplicate(Vy); + dimensionY = O.getDimension(); + OdataPtr = (double*)O.getDataPointer(); + Ocount = O[1].getIndexCount(); + } + else + { + dimensionY = Vy.getDimension(); + OdataPtr = (double*)Vy.getDataPointer(); + Ocount = Vy[1].getIndexCount(); + } + + if(M != Ocount) + {CAMmvaGraphics::ordinateError(Vy.Structure);} + + + if((dimensionX != 1)||(dimensionY != 1)) return; + +// +// get reference to the graphics base class +// + CAMgraphicsProcess& G = *this; +// +// plot +// + switch(callType) + { + case 0 : G.plot(AdataPtr,OdataPtr,M); break; + case 1 : G.plot(AdataPtr,OdataPtr,M,p_arg); break; + case 2 : G.plot(AdataPtr,OdataPtr,M,p_arg,p_style); break; + } + +} +// +//****************************************************************************** +//****************************************************************************** +// CONTOUR +//****************************************************************************** +//****************************************************************************** +// +void CAMmvaGraphics::arrayBaseContour(const CAMarrayBase& V, int callType, +int nCntr, double cIncr, double lVal, double hVal, const CAMarrayBase* contourValues) +{ +// +// Need Conversion Check +// +// +// Unpack data +// + long M; long N; + CAMarrayBase A; + double* AdataPtr; + + long dimension; + + if(V.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(V); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension != 2) return; + M = A[1].getIndexCount(); + N = A[2].getIndexCount(); + } + else + { + dimension = V.getDimension(); + AdataPtr = (double*)(V.getDataPointer()); + if(dimension != 2) return; + M = V[1].getIndexCount(); + N = V[2].getIndexCount(); + } +// +// Unpack contour values if required +// + long Ncntr; + CAMarrayBase cntrVal; + double* cntrValDataPtr; + + if(contourValues != 0) + { + if((*contourValues).Structure.isSubset() == 1) + { + cntrVal.initializeMinDuplicate(V); + cntrValDataPtr = (double*)cntrVal.getDataPointer(); + Ncntr = cntrVal[1].getIndexCount(); + } + else + { + cntrValDataPtr = (double*)((*contourValues).getDataPointer()); + Ncntr = (*contourValues)[1].getIndexCount(); + } + } +// +// get reference to the graphics base class +// +// +// Contour Plot +// + double* Cdata = new double[M*N]; + long i; long j; + for(i = 0; i < M; i++) + { + for(j = 0; j < N; j++) + { + *(Cdata + j + i*N) = *(AdataPtr + i + j*M); + }} + CAMgraphicsProcess& G = *this; + switch(callType) + { + case 0 : G.contour(Cdata,M,N); break; + case 1 : G.contour(Cdata,M,N,nCntr); break; + case 2 : G.contour(Cdata,M,N,cIncr); break; + case 3 : G.contour(Cdata,M,N,lVal,hVal); break; + case 4 : G.contour(Cdata,M,N,nCntr,lVal,hVal); break; + case 5 : G.contour(Cdata,M,N,cIncr,lVal,hVal); break; + case 6 : G.contour(Cdata,M,N,cntrValDataPtr,Ncntr); break; + } + delete [] Cdata; +} + +void CAMmvaGraphics::contour(const CAMarrayBase& V) +{ + int callType = 0; + int nCntr = 0; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + +} +void CAMmvaGraphics::contour(const CAMarrayBase& V, int nContour) +{ + int callType = 1; + int nCntr = nContour; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + +} + +void CAMmvaGraphics::contour(const CAMarrayBase& V, long nContour) +{ + int callType = 1; + int nCntr = (int)nContour; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} + +void CAMmvaGraphics::contour(const CAMarrayBase& V, double increment) +{ + int callType = 2; + int nCntr = 0; + double cIncr = increment; + double lVal = 0.0; + double hVal = 0.0; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} + +void CAMmvaGraphics::contour(const CAMarrayBase& V, double low_value, +double high_value) +{ + int callType = 3; + int nCntr = 0; + double cIncr = 0.0; + double lVal = low_value; + double hVal = high_value; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + + +} +void CAMmvaGraphics::contour(const CAMarrayBase& V, int nContour, +double low_value, double high_value) +{ + int callType = 4; + int nCntr = nContour; + double cIncr = 0.0; + double lVal = low_value; + double hVal = high_value; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + +} +void CAMmvaGraphics::contour(const CAMarrayBase& V, long nContour, +double low_value, double high_value) +{ + + int callType = 4; + int nCntr = (int)nContour; + double cIncr = 0.0; + double lVal = low_value; + double hVal = high_value; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} +void CAMmvaGraphics::contour(const CAMarrayBase& V, double increment, +double low_value, double high_value) +{ + int callType = 5; + int nCntr = 0; + double cIncr = increment; + double lVal = low_value; + double hVal = high_value; + CAMarrayBase* contourValues = 0; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} + +void CAMmvaGraphics::contour(const CAMarrayBase& V, const CAMarrayBase& cValues) +{ + int callType = 6; + int nCntr = 0; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + const CAMarrayBase* contourValues = &cValues; + + arrayBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} +// +//****************************************************************************** +//****************************************************************************** +// SURFACE +//****************************************************************************** +//****************************************************************************** +// +void CAMmvaGraphics::arrayBaseSurface(const CAMarrayBase& V, int callType, +const CAMarrayBase* x, const CAMarrayBase* y) +{ +// +// Need Conversion Check +// +// +// Unpack data +// + long M; long N; + CAMarrayBase A; + double* AdataPtr; + + long dimension; + + if(V.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(V); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension != 2) return; + M = A[1].getIndexCount(); + N = A[2].getIndexCount(); + } + else + { + dimension = V.getDimension(); + AdataPtr = (double*)(V.getDataPointer()); + if(dimension != 2) return; + M = V[1].getIndexCount(); + N = V[2].getIndexCount(); + } +// +// Unpack axis values if required +// + long Nx; long Ny; + CAMarrayBase xB; + CAMarrayBase yB; + double* xBDataPtr; + double* yBDataPtr; + + if((x != 0)&&(y != 0)) + { + + if((*x).Structure.isSubset() == 1) + { + xB.initializeMinDuplicate(*x); + xBDataPtr = (double*)xB.getDataPointer(); + Nx = xB[1].getIndexCount(); + } + else + { + xBDataPtr = (double*)((*x).getDataPointer()); + Nx = (*x)[1].getIndexCount(); + } + + if((*y).Structure.isSubset() == 1) + { + yB.initializeMinDuplicate(*y); + yBDataPtr = (double*)yB.getDataPointer(); + Ny = yB[1].getIndexCount(); + } + else + { + yBDataPtr = (double*)((*y).getDataPointer()); + Ny = (*y)[1].getIndexCount(); + } + + if(M != Nx) + {CAMmvaGraphics::ordinateError(x->Structure);} + + if(N != Ny) + {CAMmvaGraphics::ordinateError(y->Structure);} + + + } + + double* Cdata = new double[M*N]; + long i; long j; + for(i = 0; i < M; i++) + { + for(j = 0; j < N; j++) + { + *(Cdata + j + i*N) = *(AdataPtr + i + j*M); + }} + + CAMgraphicsProcess& G = *this; + switch(callType) + { + case 0 : G.surface(Cdata,M,N); break; + case 1 : G.surface(Cdata,M,N,xBDataPtr, yBDataPtr); break; + } + delete [] Cdata; +} + +void CAMmvaGraphics::surface(const CAMarrayBase& V) +{ + int callType = 0; + CAMarrayBase* xP = 0; + CAMarrayBase* yP = 0; + arrayBaseSurface(V, callType, xP, yP); +} +void CAMmvaGraphics::surface(const CAMarrayBase& V,const CAMarrayBase& x, +const CAMarrayBase& y) +{ + int callType = 1; + const CAMarrayBase* xP = &x; + const CAMarrayBase* yP = &y; + arrayBaseSurface(V, callType, xP, yP); +} + + + + + +// +//****************************************************************************** +//****************************************************************************** +// Graphics Bindings for CAMmatrixBase +//****************************************************************************** +//****************************************************************************** +// + +// +//****************************************************************************** +//****************************************************************************** +// PLOT +//****************************************************************************** +//****************************************************************************** +// + +void CAMmvaGraphics::plot(const CAMmatrixBase& V) +{ + int p_arg = 0; + int p_style = 0; + int callType = 0; + matrixBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMmatrixBase& V, int p_arg) +{ + int p_style = 0; + int callType = 1; + matrixBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMmatrixBase& V, int p_arg, int p_style) +{ + int callType = 2; + matrixBasePlot(V,callType, p_arg, p_style); +} + +void CAMmvaGraphics::matrixBasePlot(const CAMmatrixBase& V, int callType, +int p_arg, int p_style) +{ +// +// Need Conversion Check +// +// +// extract data from vector +// + long M; + CAMmatrixBase A; + double* AdataPtr; + + long dimension; + + if(V.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(V); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + M = A[1].getIndexCount(); + } + else + { + dimension = V.getDimension(); + AdataPtr = (double*)(V.getDataPointer()); + M = V[1].getIndexCount(); + } + + if(dimension != 1) return; +// +// get reference to the graphics base class +// + CAMgraphicsProcess& G = *this; +// +// plot +// + switch(callType) + { + case 0 : G.plot(AdataPtr,M); break; + case 1 : G.plot(AdataPtr,M,p_arg); break; + case 2 : G.plot(AdataPtr,M,p_arg,p_style); break; + } +} + +void CAMmvaGraphics::plot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy) +{ + int p_arg = 0; + int p_style = 0; + int callType = 0; + matrixBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy, +int p_arg) +{ + int p_style = 0; + int callType = 1; + matrixBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::plot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy, +int p_arg, int p_style) +{ + int callType = 2; + matrixBasePlot(Vx,Vy,callType, p_arg, p_style); +} + +void CAMmvaGraphics::matrixBasePlot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy, +int callType, int p_arg, int p_style) +{ +// +// Need Conversion Check +// + long dimensionX; + long dimensionY; + + long M; + + CAMmatrixBase A; + double* AdataPtr; + + CAMmatrixBase O; + double* OdataPtr; + long Ocount; + + if(Vx.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(Vx); + dimensionX = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + M = A[1].getIndexCount(); + } + else + { + dimensionX = Vx.getDimension(); + AdataPtr = (double*)Vx.getDataPointer(); + M = Vx[1].getIndexCount(); + } + + if(Vy.Structure.isSubset() == 1) + { + O.initializeMinDuplicate(Vy); + dimensionY = O.getDimension(); + OdataPtr = (double*)O.getDataPointer(); + Ocount = O[1].getIndexCount(); + } + else + { + dimensionY = Vy.getDimension(); + OdataPtr = (double*)Vy.getDataPointer(); + Ocount = Vy[1].getIndexCount(); + } + + if(M != Ocount) + {CAMmvaGraphics::ordinateError(Vy.Structure);} + + + if((dimensionX != 1)||(dimensionY != 1)) return; + +// +// get reference to the graphics base class +// + CAMgraphicsProcess& G = *this; +// +// plot +// + switch(callType) + { + case 0 : G.plot(AdataPtr,OdataPtr,M); break; + case 1 : G.plot(AdataPtr,OdataPtr,M,p_arg); break; + case 2 : G.plot(AdataPtr,OdataPtr,M,p_arg,p_style); break; + } + +} +// +//****************************************************************************** +//****************************************************************************** +// CONTOUR +//****************************************************************************** +//****************************************************************************** +// +void CAMmvaGraphics::matrixBaseContour(const CAMmatrixBase& V, int callType, +int nCntr, double cIncr, double lVal, double hVal, const CAMmatrixBase* contourValues) +{ +// +// Need Conversion Check +// +// +// Unpack data (transfrom to doubleArray so I can use _ notation) +// + long M; long N; + double* AdataPtr; + + CAMdoubleMatrix B = V; + CAMdoubleMatrix A = V; + + M = A[1].getIndexCount(); + N = A[2].getIndexCount(); + + long i; + for(i = 1; i <= M; i++) + {A(i,_) = B(M - (i-1),_);} + + AdataPtr = A.getDataPointer(); +// +// Repack the data so that the (1,1) element is the upper left; not the +// lower left +// + +// +// Unpack contour values if required +// + long Ncntr; + CAMmatrixBase cntrVal; + double* cntrValDataPtr; + + if(contourValues != 0) + { + if((*contourValues).Structure.isSubset() == 1) + { + cntrVal.initializeMinDuplicate(V); + cntrValDataPtr = (double*)cntrVal.getDataPointer(); + Ncntr = cntrVal[1].getIndexCount(); + } + else + { + cntrValDataPtr = (double*)((*contourValues).getDataPointer()); + Ncntr = (*contourValues)[1].getIndexCount(); + } + } +// +// get reference to the graphics base class +// +// +// Contour Plot +// + CAMgraphicsProcess& G = *this; + switch(callType) + { + case 0 : G.contour(AdataPtr,N,M); break; + case 1 : G.contour(AdataPtr,N,M,nCntr); break; + case 2 : G.contour(AdataPtr,N,M,cIncr); break; + case 3 : G.contour(AdataPtr,N,M,lVal,hVal); break; + case 4 : G.contour(AdataPtr,N,M,nCntr,lVal,hVal); break; + case 5 : G.contour(AdataPtr,N,M,cIncr,lVal,hVal); break; + case 6 : G.contour(AdataPtr,N,M,cntrValDataPtr,Ncntr); break; + } + +} + +void CAMmvaGraphics::contour(const CAMmatrixBase& V) +{ + int callType = 0; + int nCntr = 0; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + +} +void CAMmvaGraphics::contour(const CAMmatrixBase& V, int nContour) +{ + int callType = 1; + int nCntr = nContour; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + +} + +void CAMmvaGraphics::contour(const CAMmatrixBase& V, long nContour) +{ + int callType = 1; + int nCntr = (int)nContour; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} + +void CAMmvaGraphics::contour(const CAMmatrixBase& V, double increment) +{ + int callType = 2; + int nCntr = 0; + double cIncr = increment; + double lVal = 0.0; + double hVal = 0.0; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} + +void CAMmvaGraphics::contour(const CAMmatrixBase& V, double low_value, +double high_value) +{ + int callType = 3; + int nCntr = 0; + double cIncr = 0.0; + double lVal = low_value; + double hVal = high_value; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + + +} +void CAMmvaGraphics::contour(const CAMmatrixBase& V, int nContour, +double low_value, double high_value) +{ + int callType = 4; + int nCntr = nContour; + double cIncr = 0.0; + double lVal = low_value; + double hVal = high_value; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); + +} +void CAMmvaGraphics::contour(const CAMmatrixBase& V, long nContour, +double low_value, double high_value) +{ + + int callType = 4; + int nCntr = (int)nContour; + double cIncr = 0.0; + double lVal = low_value; + double hVal = high_value; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} +void CAMmvaGraphics::contour(const CAMmatrixBase& V, double increment, +double low_value, double high_value) +{ + int callType = 5; + int nCntr = 0; + double cIncr = increment; + double lVal = low_value; + double hVal = high_value; + CAMmatrixBase* contourValues = 0; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} + +void CAMmvaGraphics::contour(const CAMmatrixBase& V, const CAMmatrixBase& cValues) +{ + int callType = 6; + int nCntr = 0; + double cIncr = 0.0; + double lVal = 0.0; + double hVal = 0.0; + const CAMmatrixBase* contourValues = &cValues; + + matrixBaseContour(V, callType, nCntr, cIncr, lVal, hVal, contourValues); +} +// +//****************************************************************************** +//****************************************************************************** +// SURFACE +//****************************************************************************** +//****************************************************************************** +// +void CAMmvaGraphics::matrixBaseSurface(const CAMmatrixBase& V, int callType, +const CAMmatrixBase* x, const CAMmatrixBase* y) +{ +// +// Need Conversion Check +// +// +// Unpack data +// + long M; long N; + CAMmatrixBase A; + double* AdataPtr; + + long dimension; + + if(V.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(V); + dimension = A.getDimension(); + AdataPtr = (double*)A.getDataPointer(); + if(dimension != 2) return; + M = A[1].getIndexCount(); + N = A[2].getIndexCount(); + } + else + { + dimension = V.getDimension(); + AdataPtr = (double*)(V.getDataPointer()); + if(dimension != 2) return; + M = V[1].getIndexCount(); + N = V[2].getIndexCount(); + } +// +// Unpack axis values if required +// + long Nx; long Ny; + CAMmatrixBase xB; + CAMmatrixBase yB; + double* xBDataPtr; + double* yBDataPtr; + + if((x != 0)&&(y != 0)) + { + + if((*x).Structure.isSubset() == 1) + { + xB.initializeMinDuplicate(*x); + xBDataPtr = (double*)xB.getDataPointer(); + Nx = xB[1].getIndexCount(); + } + else + { + xBDataPtr = (double*)((*x).getDataPointer()); + Nx = (*x)[1].getIndexCount(); + } + + if((*y).Structure.isSubset() == 1) + { + yB.initializeMinDuplicate(*y); + yBDataPtr = (double*)yB.getDataPointer(); + Ny = yB[1].getIndexCount(); + } + else + { + yBDataPtr = (double*)((*y).getDataPointer()); + Ny = (*y)[1].getIndexCount(); + } + + if(M != Nx) + {CAMmvaGraphics::ordinateError(x->Structure);} + + if(N != Ny) + {CAMmvaGraphics::ordinateError(y->Structure);} + + + } +// +// get reference to the graphics base class +// +// +// Contour Plot +// + CAMgraphicsProcess& G = *this; + switch(callType) + { + case 0 : G.surface(AdataPtr,N,M); break; + case 1 : G.surface(AdataPtr,N,M,xBDataPtr, yBDataPtr); break; + } +} + +void CAMmvaGraphics::surface(const CAMmatrixBase& V) +{ + int callType = 0; + CAMmatrixBase* xP = 0; + CAMmatrixBase* yP = 0; + matrixBaseSurface(V, callType, xP, yP); +} +void CAMmvaGraphics::surface(const CAMmatrixBase& V,const CAMmatrixBase& x, +const CAMmatrixBase& y) +{ + int callType = 1; + const CAMmatrixBase* xP = &x; + const CAMmatrixBase* yP = &y; + matrixBaseSurface(V, callType, xP, yP); +} + +void CAMmvaGraphics::ordinateError(const CAMstructureBase & A) +{ + long i; + cerr << endl; + cerr << " Ordinates in Plot Command Incorrectly Specified " << endl << endl; + cerr << " Error in Number of Ordinates or Ordinate Array Dimension " << endl; + cerr << " Ordinates Size : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} + + + + + + + + + + diff --git a/src/matrix/mvagph.h b/src/matrix/mvagph.h new file mode 100755 index 0000000..9117bbb --- /dev/null +++ b/src/matrix/mvagph.h @@ -0,0 +1,108 @@ +// +//****************************************************************************** +// MVAGPH.H +//****************************************************************************** +// +#include "cammva.h" +#include "gprocess.h" +#include "mvaimpexp.h" +// +//****************************************************************************** +// +// Chris Anderson (C) UCLA 1997 +// 8/1/97 +// +// +//****************************************************************************** +// + +#ifndef __CAM_MVA_GRAPHICS__ +#define __CAM_MVA_GRAPHICS__ +class __IMPEXP__ CAMmvaGraphics : public CAMgraphicsProcess +{ +public : + + CAMmvaGraphics(); +// +// Routines for CAMdoubleVector +// + void plot(const CAMvectorBase& V); + void plot(const CAMvectorBase& V, int p_arg); + void plot(const CAMvectorBase& V, int p_arg, int p_style); + + void plot(const CAMvectorBase& Vx, const CAMvectorBase& Vy); + void plot(const CAMvectorBase& Vx, const CAMvectorBase& Vy, int p_arg); + void plot(const CAMvectorBase& Vx, const CAMvectorBase& Vy, int p_arg, int p_style); +// +// CAMdoubleArray +// + void plot(const CAMarrayBase& V); + void plot(const CAMarrayBase& V, int p_arg); + void plot(const CAMarrayBase& V, int p_arg, int p_style); + + void plot(const CAMarrayBase& Vx, const CAMarrayBase& Vy); + void plot(const CAMarrayBase& Vx, const CAMarrayBase& Vy, int p_arg); + void plot(const CAMarrayBase& Vx, const CAMarrayBase& Vy, int p_arg, int p_style); + + void contour(const CAMarrayBase& V); + void contour(const CAMarrayBase& V, int nContour); + void contour(const CAMarrayBase& V, long nContour) ; + void contour(const CAMarrayBase& V, double increment); + void contour(const CAMarrayBase& V, double low_value, double high_value); + void contour(const CAMarrayBase& V, int nContour, double low_value, double high_value); + void contour(const CAMarrayBase& V, long nContour, double low_value, double high_value); + void contour(const CAMarrayBase& V, double increment, double low_value, double high_value); + void contour(const CAMarrayBase& V, const CAMarrayBase& contourValues); + + void surface(const CAMarrayBase& V); + void surface(const CAMarrayBase& V,const CAMarrayBase& x, const CAMarrayBase& y); +// +// Routines for CAMdoubleMatrix +// + void plot(const CAMmatrixBase& V); + void plot(const CAMmatrixBase& V, int p_arg); + void plot(const CAMmatrixBase& V, int p_arg, int p_style); + + void plot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy); + void plot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy, int p_arg); + void plot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy, int p_arg, int p_style); + + void contour(const CAMmatrixBase& V); + void contour(const CAMmatrixBase& V, int nContour); + void contour(const CAMmatrixBase& V, long nContour) ; + void contour(const CAMmatrixBase& V, double increment); + void contour(const CAMmatrixBase& V, double low_value, double high_value); + void contour(const CAMmatrixBase& V, int nContour, double low_value, double high_value); + void contour(const CAMmatrixBase& V, long nContour, double low_value, double high_value); + void contour(const CAMmatrixBase& V, double increment, double low_value, double high_value); + void contour(const CAMmatrixBase& V, const CAMmatrixBase& contourValues); + + void surface(const CAMmatrixBase& V); + void surface(const CAMmatrixBase& V,const CAMmatrixBase& x, const CAMmatrixBase& y); + + +private : + + void vectorBasePlot(const CAMvectorBase& V, int callType, int p_arg, int p_style); + void vectorBasePlot(const CAMvectorBase& Vx, const CAMvectorBase& Vy, int callType, int p_arg, int p_style); + + void arrayBasePlot(const CAMarrayBase& V, int callType, int p_arg, int p_style); + void arrayBasePlot(const CAMarrayBase& Vx, const CAMarrayBase& Vy, int callType, int p_arg, int p_style); + void arrayBaseContour(const CAMarrayBase& V, int callType, int nCntr, double cIncr, + double lVal, double hVal, const CAMarrayBase* contourValues); + void arrayBaseSurface(const CAMarrayBase& V, int callType, const CAMarrayBase* x, + const CAMarrayBase* y); + + + void matrixBasePlot(const CAMmatrixBase& V, int callType, int p_arg, int p_style); + void matrixBasePlot(const CAMmatrixBase& Vx, const CAMmatrixBase& Vy, int callType, int p_arg, int p_style); + void matrixBaseContour(const CAMmatrixBase& V, int callType, int nCntr, double cIncr, + double lVal, double hVal, const CAMmatrixBase* contourValues); + void matrixBaseSurface(const CAMmatrixBase& V, int callType, const CAMmatrixBase* x, + const CAMmatrixBase* y); + + void ordinateError(const CAMstructureBase & A); + +}; +#endif + diff --git a/src/matrix/mvaimpexp.h b/src/matrix/mvaimpexp.h new file mode 100755 index 0000000..133042e --- /dev/null +++ b/src/matrix/mvaimpexp.h @@ -0,0 +1,36 @@ +// +// Import/Export Directive for CAMmva DLL +// +// Chris Anderson (C) UCLA 1997 +// +#undef __IMPEXP__ + +#ifdef __BCPLUSPLUS__ +#ifdef __EXPORT_CAMMVA__ +#define __IMPEXP__ __declspec(dllexport) +#endif +#ifdef __USEDLL__ +#define __IMPEXP__ __declspec(dllimport) +#endif +#endif + + +#ifdef _MSC_VER +#ifdef __EXPORT_CAMMVA__ +#define __IMPEXP__ __declspec(dllexport) +#endif +#ifdef __USEDLL__ +#define __IMPEXP__ __declspec(dllimport) +#endif +#endif + + +#ifdef __STATIC__ +#undef __IMPEXP__ +#define __IMPEXP__ +#endif + +#ifndef __IMPEXP__ +#define __IMPEXP__ +#endif + diff --git a/src/matrix/mvalngbase.cpp b/src/matrix/mvalngbase.cpp new file mode 100755 index 0000000..157fc97 --- /dev/null +++ b/src/matrix/mvalngbase.cpp @@ -0,0 +1,443 @@ +#include "mvalngbase.h" +#include "string.h" +#include "stdlib.h" + +// +//****************************************************************************** +// MVALNGBASE.CPP +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// +//******************************************************************************** +// +// +//******************************************************************************** +// CONSTRUCTORS +//******************************************************************************** +// + +#define longNullValue 0 + +MVAlongBase::MVAlongBase() +{ + dataPointer = newLong(0); + size = 0; +} + +MVAlongBase::MVAlongBase( const MVAlongBase& A) +{ + if(A.size == 0) + {dataPointer = newLong(0); size = 0;} + else + { + dataPointer = newLong(A.size); + size = A.size; + long* Aptr; + long* ptr; + for(Aptr = A.dataPointer, ptr = dataPointer; + Aptr < A.dataPointer + A.size; Aptr++, ptr++) + *ptr = *Aptr; + } +} + + +MVAlongBase::MVAlongBase(long inSize) +{ + dataPointer = newLong(inSize); + size = inSize; +} +MVAlongBase::MVAlongBase(long* data, long inSize) +{ + dataPointer = newLong(inSize); + size = inSize; + long* ptr; + long* dptr; + for(ptr = dataPointer, dptr = data;dptr < data + inSize; + ptr++, dptr++) + *ptr = *dptr; +} +// +//******************************************************************************** +// DESTRUCTOR +//******************************************************************************** +// +MVAlongBase::~MVAlongBase() +{ + deleteLong(); + size = 0; +} + +// +//******************************************************************************** +// INPUT/OUTPUT +//******************************************************************************** +// +ostream& operator <<(ostream& out_stream, const MVAlongBase& A) +{ + for(long i = 0; i < A.size; i++) + out_stream << A.dataPointer[i] << '\n'; + return(out_stream); +} + +istream& operator >>(istream& in, MVAlongBase& A) +{ + MVAlongBase::inputLong(in, A); + return(in); +} +// +//******************************************************************************** +// ASSIGNMENT +//******************************************************************************** +// +MVAlongBase& MVAlongBase::operator =( const MVAlongBase& A) +{ + if(dataPointer == 0) + { dataPointer = newLong(A.size); size = A.size;} +// + if(size != A.size) + {MVAlongBase::sizeError(size, A.size);} +// + long* Aptr; long* ptr; + for(Aptr = A.dataPointer, ptr = dataPointer; + Aptr < A.dataPointer + A.size; Aptr++, ptr++) + *ptr = *Aptr; + return *this; +} +// +//******************************************************************************** +// MEMBER_FUNCTIONS +//******************************************************************************** +// +// +//******************************************************************************** +// Initalize Functions +//******************************************************************************** +// +void MVAlongBase::initialize() +{ + deleteLong(); + dataPointer = newLong(0); + size = 0; +} + +void MVAlongBase::initialize( const MVAlongBase& A) +{ + deleteLong(); + if(A.size == 0) + { + dataPointer = newLong(0); + size = 0; + } + else + { + dataPointer = newLong(A.size); + size = A.size; + long* Aptr; + long* ptr; + for(Aptr = A.dataPointer, ptr = dataPointer; + Aptr < A.dataPointer + A.size; Aptr++, ptr++) + *ptr = *Aptr; + } +} + +void MVAlongBase::initialize(long inSize) +{ + deleteLong(); + dataPointer = newLong(inSize); + size = inSize; +} + +void MVAlongBase::initialize(long* data, long inSize) +{ + deleteLong(); + dataPointer = newLong(inSize); + size = inSize; + long* ptr; + long* dptr; + for(ptr = dataPointer, dptr = data;dptr < data + inSize; + ptr++, dptr++) + *ptr = *dptr; +} + +void MVAlongBase::copyToArray(long* A) const +{ + long* ptr; + long* Aptr; + for(ptr = dataPointer,Aptr = A; ptr < dataPointer + size; + ptr++, Aptr++) + *Aptr = *ptr; +} +// +//******************************************************************************** +// Resizing +//******************************************************************************** +// +void MVAlongBase::resizeTo(long n) +{ + MVAlongBase Temp; + if( n > 0) + { + Temp.initialize(*this); + this->initialize(n); + + long* Tptr; + long* ptr; + + if(Temp.getSize() < n) + { + for(ptr = dataPointer, Tptr = Temp.getDataPointer(); + Tptr < Temp.getDataPointer() + Temp.getSize(); + Tptr++, ptr++) + *ptr = *Tptr; + } + else + { + for(ptr = dataPointer, Tptr = Temp.getDataPointer(); + ptr < dataPointer + n; + Tptr++, ptr++) + *ptr = *Tptr; + } + } + else if(n == 0) + { + deleteLong(); + dataPointer = newLong(0); + size = 0; + } + else + {MVAlongBase::reSizeError(n);} +}; +// +//******************************************************************************** +// Logical Equality and Inequality +//******************************************************************************** +// +int MVAlongBase::operator == (const MVAlongBase& A) const +{ + if(size != A.size) return 0; + if(size == 0 ) return 1; + + for(long i = 0; i < size ; i++) + if(dataPointer[i] != A.dataPointer[i]) return 0; + + return 1; +} + +int MVAlongBase::operator != (const MVAlongBase& A) const +{ + if(size != A.size) return 1; + if(size == 0 ) return 0; + + for(long i = 0; i < size ; i++) + if(dataPointer[i] != A.dataPointer[i]) return 1; + + return 0; +} +// +//******************************************************************************** +// Input Utility +//******************************************************************************** +// +void MVAlongBase::inputLong(istream& in, MVAlongBase& A) +{ +// +// This routine extracts the N values of the +// "next" sequence of long values in the input stream +// copies them into the MVAlongBase array A. +// +// By "next" sequence we mean the set of numbers contained +// in the stream which are separated by spaces or new-line +// characters. Any initial character data in the stream is +// skipped and the end of the sequence is triggered by +// encountering character data or end of file (EOF). +// +// If A has a prescribed non-zero size then this routine +// places the N values into the first N locations of A; +// the remainder of A's values are untouched. +// +// If the size of A is less than N an error message is generated. +// +// If A is of zero size (a null) array, then this routine +// resizes A to N and copies the data into A. +// +// + if(in.eof() != 0) return; + long i; + char in_char; + char in_token[128]; + + int long_hit; int char_hit; + long long_count; + + long file_position; + + file_position = in.tellg(); + long_count = 0; + + in_char = in.get(); + while((in.eof() == 0)&&((in_char == '\n')||(in_char == ' '))) + {in_char = in.get();} + + long_hit = 0; + char_hit = 0; + + while((in.eof() == 0)&&(char_hit == 0)) + { + // + // Digit Processing + // + if((48 <= int(in_char)&&(int(in_char) <= 57))) + { + long_hit = 1; + while((in.eof() == 0)&&((in_char != '\n')&& (in_char != ' '))) + {in_char = in.get();} + long_count++; + } + else + // + // Character Processing + // + { + if(long_hit == 1) {in.putback(in_char); char_hit = 1;} + while((char_hit == 0)&&(in.eof() == 0)&&((in_char != '\n') && (in_char != ' '))) + { + if(in_char == '\\') { in_char = in.get();} + in_char = in.get(); + } + } + + while((in.eof() == 0)&&((in_char == '\n')||(in_char == ' '))) + {in_char = in.get();} + + } +// +// Read in the data +// + if(A.getSize() == 0) + {A.resizeTo(long_count);} + else + { + if(A.getSize() < long_count) + {MVAlongBase::inputError( A.getSize(), long_count );} + } + + in.clear(); + in.seekg(file_position); + + in_char = in.get(); + while((in.eof() == 0)&&((in_char == '\n')||(in_char == ' '))) + {in_char = in.get();} + + long_hit = 0; + long_count = 0; + while(in.eof() == 0) + { + // + // Digit Processing + // + if((48 <= int(in_char)&&(int(in_char) <= 57))) + { + long_hit = 1; + i = 0; + while((in.eof() == 0)&&((in_char != '\n') + && (in_char != ' '))) + {in_token[i] = in_char; in_char = in.get(); i++;} + in_token[i] = '\0'; + if(strchr(in_token,'.')) + { + A[long_count] = long(strtod(in_token,NULL)); + } + else + { + A[long_count] = long(strtol(in_token,NULL,10)); + } + long_count++; + } + else + // + // Character Processing + // + { + // + // Return if have a long_hit followed by a character hit + // + if(long_hit == 1) {in.putback(in_char); return;} + while((in.eof() == 0)&&((in_char != '\n') && (in_char != ' '))) + { + if(in_char == '\\') { in_char = in.get();} + in_char = in.get(); + } + } + + while((in.eof() == 0)&&((in_char == '\n')||(in_char == ' '))) + {in_char = in.get();} + + } +} +// +//******************************************************************************** +// newLong (memory allocation) +//******************************************************************************** +// +long* MVAlongBase::newLong(long newSize) +{ + long* dataP; + if(newSize > 0) + { + dataP = new long[newSize]; + long* ptr; + for(ptr = dataP; ptr < dataP + newSize; ptr++) *ptr = longNullValue; + return dataP; + } + else + {dataP = 0; return dataP;} +} +void MVAlongBase::deleteLong() +{ + if(dataPointer != 0) delete [] dataPointer; + dataPointer = 0; +} + +// +//******************************************************************************** +// Error Handling +//******************************************************************************** +// +void MVAlongBase::inputError(long ArraySize, long RequiredSize) +{ + cerr << "MVAlongBase Array of Insufficient Size For >> Operation" + << endl << "Array Size : " << ArraySize + << endl << "Required Size : " << RequiredSize << endl; + exit(1); +} +void MVAlongBase::indexError(long Index) +{ + cerr << "Index out of range in MVAlongBase.\n"; + cerr << "Offending Index Value = " << Index << endl; + exit(1); +}; +void MVAlongBase::sizeError(long Lsize, long Rsize) +{ + cerr << "Error : Assignment of unequal sized MVAlongBase \n"; + cerr << "Left Operand : " << Lsize << endl; + cerr << "Rght Operand : " << Rsize << endl; + exit(1); +}; +void MVAlongBase::reSizeError(long size) +{ + cerr << "Error : invalid size for resizing of MVAlongBase \n"; + cerr << "Offending Size : " << size << endl; + exit(1); +}; +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + + diff --git a/src/matrix/mvalngbase.h b/src/matrix/mvalngbase.h new file mode 100755 index 0000000..768169c --- /dev/null +++ b/src/matrix/mvalngbase.h @@ -0,0 +1,118 @@ +// +//****************************************************************************** +// MVALNGBASE.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// +//******************************************************************************** +// +#ifndef __CAMMVALONGBASE__ +#define __CAMMVALONGBASE__ + +#include +#include "mvaimpexp.h" + +class __IMPEXP__ MVAlongBase +{ + +public : + + long* dataPointer; + long size; + +public : + + MVAlongBase(); + MVAlongBase( const MVAlongBase& A); + MVAlongBase(long inSize); + MVAlongBase(long* data, long inSize); +// +// Destructor +// + virtual ~MVAlongBase(); +// +// Output +// + __IMPEXP__ friend ostream& operator <<(ostream& out_stream, const MVAlongBase& A); +// +// Input +// + __IMPEXP__ friend istream& operator >>(istream& in_stream, MVAlongBase& A); +// +// Assignment +// + MVAlongBase& operator = ( const MVAlongBase& A); +// +// Initialization +// + void initialize(); + void initialize(const MVAlongBase& A); + void initialize(long inSize); + void initialize(long* data, long inSize); +// +// Resizing +// + virtual void resizeTo(long n); +// +// Access +// + long getSize() const {return size;}; + long* getDataPointer() {return dataPointer;}; + const long* getDataPointer() const{return dataPointer;}; + inline long & operator[](long Index) +{ +#ifndef NOBOUNDS + if (( Index < 0 ) || ( Index >= size)) + {MVAlongBase::indexError(Index);} +#endif + return(*(dataPointer + Index)); +}; + inline const long & operator[] (long Index ) const +{ +#ifndef NOBOUNDS + if (( Index < 0 ) || ( Index >= size)) + {MVAlongBase::indexError(Index);} +#endif + return(*(dataPointer + Index)); +}; + void copyToArray(long* A) const; +// +// Logical Operands +// + int operator == (const MVAlongBase& A) const; + int operator != (const MVAlongBase& A) const; + +protected : + +// +// Error Handling +// + static void indexError(long Index); + static void sizeError(long Lsize, long Rsize); + static void reSizeError(long size); + static void inputError(long ArraySize, long RequiredSize); +// +// Input Utility +// + static void inputLong(istream& in, MVAlongBase& A); +// +// Memory Allocation +// + virtual long* newLong(long size); + virtual void deleteLong(); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + diff --git a/src/matrix/mvasamp1.cpp b/src/matrix/mvasamp1.cpp new file mode 100755 index 0000000..23afa58 --- /dev/null +++ b/src/matrix/mvasamp1.cpp @@ -0,0 +1,58 @@ +#include "cammva.h" +#include +#include +// +//###################################################################### +// +// CAMmva Test Program #1 +// +// This program sets up a and solves a linear system of equations. +// +// +// Chris Anderson (C) UCLA 1997 +//###################################################################### +// +int main(){ + + CAMdoubleMatrix A(3,3); // declare a matrix + CAMdoubleVector b(3); // declare vectors + CAMdoubleVector x(3); + CAMdoubleVector residual(3); + + long i,j; // variables for loop index + + + for(i=1; i<= 3; i++) // nested do-loop for initializing + for(j=1; j<= 3; j++) // the matrix A. + { + A(i,j)=1.0/(double(i) + double(j)); + } + + for(i=1; i<=3; i++) // initialize b + { + b(i)=double(i); + } + + x=A/b; // solve the system A*x=b for x + residual=A*x - b; // compute the residual + + // set scientific notation output + // format + + cout.setf(ios::scientific, ios::floatfield); + + cout << " The matrix A " << endl; + cout << A; + cout << " The vector b " << endl; + cout << b; + cout << " The solution of A*x=b " << endl; + cout << x; + cout << " The residual " << endl; + cout << residual; + + cout << " Program End : Hit Any Key to Terminate " << endl; + getchar(); + return 0; +} + + diff --git a/src/matrix/mvasamp2.cpp b/src/matrix/mvasamp2.cpp new file mode 100755 index 0000000..2e3100f --- /dev/null +++ b/src/matrix/mvasamp2.cpp @@ -0,0 +1,82 @@ +#include "cammva.h" +#include +#include +#include +// +//###################################################################### +// +// CAMmva Test Program #2 +// +// This program demonstrates file input/output by constructing a matrix and +// a vector, writing it to a file, and then reading it back in. The program +// then solves the linear system represented by the matrix and the vector. +// +// Chris Andersion (C) UCLA 1997 +//###################################################################### +// +int main(){ + + CAMdoubleMatrix A(3,3); // declare a matrix + CAMdoubleMatrix M(3,3); + CAMdoubleVector b(3); // declare vectors + CAMdoubleVector rhs(3); + CAMdoubleVector x(3); + CAMdoubleVector residual(3); +// +// Open a file and write out a matrix and a right hand side +// + ofstream OutFile; // declare an output file stream + OutFile.open("Test.dat",ios::out); // + + long i,j; // variables for loop index + + + for(i=1; i<= 3; i++) // nested do-loop for initializing + for(j=1; j<= 3; j++) // the matrix M. + { + M(i,j)=1.0/(double(i) + double(j)); + } + + for(i=1; i<=3; i++) // initialize rhs + { + rhs(i)=double(i); + } + OutFile << M; + OutFile << rhs; + OutFile.close(); +// +// Open file and read back in the matrix and solve the system +// + ifstream InFile; // declare an input file stream + + // connect the file stream with + InFile.open("Test.dat",ios::in); // the external file tinput + if (!InFile ) + {cerr << " Error in Opening input File "; exit(1); } + + InFile >> A; // read in the matrix A + InFile >> b; // read in the vector b + + x=A/b; // solve the system A*x=b for x + residual=A*x - b; // compute the residual + + // set scientific notation output + // format + + cout.setf(ios::scientific, ios::floatfield); + + cout << " The matrix A " << endl; + cout << A; + cout << " The vector b " << endl; + cout << b; + cout << " The solution of A*x=b " << endl; + cout << x; + cout << " The residual " << endl; + cout << residual; + + cout << " Program End : Hit Any Key to Terminate " << endl; + getchar(); + return 0; +} + + diff --git a/src/matrix/mvasamp3.cpp b/src/matrix/mvasamp3.cpp new file mode 100755 index 0000000..215f1ed --- /dev/null +++ b/src/matrix/mvasamp3.cpp @@ -0,0 +1,136 @@ +#include "cammva.h" +#include +#include +#include +#include +// +//###################################################################### +// +// CAMmva Test Program #3 +// +// This program demonstrates the use of sub-matrix and sub-vector access, +// and index range access, by implementing a naive Gaussian elimination routine +// and a Gaussian elimination routine with partial pivoting. +// +// Chris Andersion (C) UCLA 1997 +//###################################################################### +// +int main() +{ + + long N = 5; + + CAMdoubleMatrix M(N,N); + CAMdoubleVector B(N); + CAMdoubleVector X(N); + +// +// Initialize a test matrix and right hand side +// + long i,j; + for(i=1; i<= N; i++) + for(j=1; j<= N; j++) + { + M(i,j)=1.0/(double(i) + double(j)); + } + + for(i=1; i<=N; i++) + { + B(i)=double(i); + } + + cout << " Test Matrix " << endl; + cout << M << endl; + cout << " Test Right Hand Side " << endl; + cout << B << endl; +// +// Standard Gaussian Elimination (without pivoting) +// + CAMdoubleMatrix A(N,N+1); + CAMdoubleMatrix Z(1,N+1); + + A(_(1,N),_(1,N)) =M; + A(_,N+1) =B; + + for(j=1; j<=N-1; j++) + { + for(i=j+1; i<=N; i++) + { + A(i,_) = A(i,_) - (A(i,j)/A(j,j))*A(j,_); + }} +// +// Back Solve +// + X(N) = A(N,N+1)/A(N,N); + + for(i=N-1; i>= 1; i--) + { + X(i) = A(i,N+1)/A(i,i); + for(j=i+1; j<= N; j++) + { + X(i) = X(i) -(A(i,j)/A(i,i))*X(j); + }} + + cout << "Residual with standard Gaussian elimination " << endl; + cout << M*X - B << endl; + +// +// Partial Pivoting +// + + A(1,_(1,N)) = M(3,_); + A(2,_(1,N)) = M(2,_); + A(3,_(1,N)) = M(1,_); + A(1,N+1) = B(3); + A(2,N+1) = B(2); + A(3,N+1) = B(1); + + CAMdoubleMatrix TMP(1,N+1); + + double pmax; + long imax; + + for(j=1; j<=N-1; j++) + { + + pmax = fabs(A(j,j)); + imax = j; + for(i = j+1; i <=N; i++) + { + if(fabs(A(i,j)) > pmax){pmax = A(i,j); imax = i;} + } + TMP = A(j,_); + A(j,_) = A(imax,_); + A(imax,_) = TMP; + + for(i=j+1; i<=N; i++) + { + A(i,_) = A(i,_) - (A(i,j)/A(j,j))*A(j,_); + }} +// +// Back Solve +// + X(N) = A(N,N+1)/A(N,N); + + for(i=N-1; i>= 1; i--) + { + X(i) = A(i,N+1)/A(i,i); + for(j=i+1; j<= N; j++) + { + X(i) = X(i) -(A(i,j)/A(i,i))*X(j); + }} + + cout << "Residual with Gaussian elimination and pivoting " << endl; + cout << M*X - B << endl; + + + cout << M/B - X << endl; + + cout << M*(M/B) - B << endl; + + cout << " Program End : Hit Any Key to Terminate " << endl; + getchar(); + return 0; +} + + diff --git a/src/matrix/mvasamp4.cpp b/src/matrix/mvasamp4.cpp new file mode 100755 index 0000000..8b4bf17 --- /dev/null +++ b/src/matrix/mvasamp4.cpp @@ -0,0 +1,133 @@ +#include "cammva.h" +#include "mvagph.h" +#include +#include +#include +#include + +double f(double x,double y) +{ +return (3*(1-x)*(1-x)*(exp(-x*x - (y+1)*(y+1))) + -10*(x/5 - x*x*x - y*y*y*y*y)*(exp(-x*x - y*y)) + -(1/3.0)*(exp(-(x+1)*(x+1) - y*y))); + +}; + +int main() +{ + + long N = 5; + CAMdoubleVector B(N); + CAMdoubleVector X(N); + + CAMmvaGraphics Mgraphics; // set up for mva graphics process + CAMpostScriptDriver PSdriver("graph.ps"); // set up output driver + Mgraphics.attachDriver(PSdriver); // attach driver +// +// Initialize a test matrix and right hand side +// + long i; long j; + for(i=1; i<=N; i++) + { + B(i)=double(i); + X(i)=double(i)*.25; + } + B(3) = -1; + +/* + + Mgraphics.plot(B); + Mgraphics.frame(); + Mgraphics.plot(B,'G'); + Mgraphics.frame(); + Mgraphics.plot(B,'H',CAMgraphicsProcess::CURVE_AND_POINTS); + Mgraphics.frame(); + Mgraphics.plot(X,B); + Mgraphics.frame(); + Mgraphics.plot(X,B,'G'); + Mgraphics.frame(); + Mgraphics.plot(X,B,'H',CAMgraphicsProcess::CURVE_AND_POINTS); + Mgraphics.frame(); + +*/ + + long m; long n; + + m = 10; + n = 40; + CAMdoubleArray A(m,n); + CAMdoubleArray XP(n); + for(i= 1; i <= m; i++) + { + for(j = 1; j <=n; j++) + { + A(i,j) = cos(double(i)*3.14159*2.0*double(j-1)*(1.0)/double(n-1)); + }} + + for(j = 1; j <= n; j++) + { + XP(j) = double(j-1)/double(n-1); + } + + /* + Mgraphics.plot(A(1,_)); + Mgraphics.frame(); + Mgraphics.plot(A(2,_),CAMgraphicsProcess::CURVE_AND_POINTS); + Mgraphics.frame(); + Mgraphics.plot(A(3,_),'+'); + Mgraphics.frame(); + + Mgraphics.plot(XP,A(1,_)); + Mgraphics.frame(); + Mgraphics.plot(XP,A(2,_),CAMgraphicsProcess::CURVE_AND_POINTS); + Mgraphics.frame(); + Mgraphics.plot(XP,A(3,_),'+'); + Mgraphics.frame(); + */ + + m = 30; + n = 30; + + CAMdoubleMatrix C(m,n); + + double a = -3.0; // create data for contour plot + double b = 3.0; + double c = -3.0; + double d = 3.0; + + + double hx = (b-a)/double(m-1); + double hy = (d-c)/double(n-1); + + for(i =1; i <= m; i++) + { + for(j =1; j <=n; j++) + { + C(i,j) = f(a + double(i-1)*hx, c + double(j-1)*hy); + C(i,j) = 0.0; + }} + + C(5,5) = 1.0; + C(n-3,n-3) = 1.0; + + Mgraphics.contour(C); + Mgraphics.frame(); +/* + Mgraphics.contour(C,10); + Mgraphics.frame(); + Mgraphics.contour(C,.1); + Mgraphics.frame(); + Mgraphics.contour(C,0.0,1.0); + Mgraphics.frame(); + Mgraphics.contour(C,10,0.0,1.0); + Mgraphics.frame(); + Mgraphics.contour(C,XP); +*/ + Mgraphics.surface(C); + Mgraphics.frame(); + + + cout << " Program End : Hit Any Key to Terminate " << endl; + getchar(); + return 0; +} diff --git a/src/matrix/range.cpp b/src/matrix/range.cpp new file mode 100755 index 0000000..822da4e --- /dev/null +++ b/src/matrix/range.cpp @@ -0,0 +1,253 @@ +#include "range.h" +#include "mvaexit.h" +// +//****************************************************************************** +// RANGE.CPP +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Fri Sep 01 18:43:55 1995 +// +//******************************************************************************** +// +// Global Instance CAMnullRange; +// +//CAMrange __IMPEXP__ CAMnullRange; +// +//******************************************************************************** +// CONSTRUCTORS +//******************************************************************************** +// +// +//******************************************************************************** +// +//******************************************************************************** +// +CAMrange::CAMrange() +{ + base = 0; + bound = 0; + stride = 0; + singleArgumentFlag = 0; + underscoreFlag = 0; + nullFlag = 1; +} + +CAMrange::CAMrange( const CAMrange& A) +{ + base = A.base; + bound = A.bound; + stride = A.stride; + singleArgumentFlag = A.singleArgumentFlag; + underscoreFlag = A.underscoreFlag; + nullFlag = A.nullFlag; +} + +CAMrange::CAMrange(long inputSize) +{ + base = 1; + bound = inputSize; + stride = 1; + singleArgumentFlag = 1; + underscoreFlag = 0; + nullFlag = 0; + CAMrange::CAMrangeError(*this); +} +CAMrange::CAMrange(long inputBase, long inputBound) +{ + base = inputBase; + bound = inputBound; + stride = 1; + singleArgumentFlag = 0; + underscoreFlag = 0; + nullFlag = 0; + CAMrange::CAMrangeError(*this); +} +CAMrange::CAMrange(long inputBase, long inputBound, long inputStride) +{ + base = inputBase; + bound = inputBound; + stride = inputStride; + singleArgumentFlag = 0; + underscoreFlag = 0; + nullFlag = 0; + CAMrange::CAMrangeError(*this); +} +CAMrange::CAMrange(const CAMunderscore&) +{ + base = 0; + bound = 0; + stride = 0; + singleArgumentFlag = 0; + underscoreFlag = 1; + nullFlag = 0; +} +// +//******************************************************************************** +// DESTRUCTOR +//******************************************************************************** +// +CAMrange::~CAMrange() +{ +} +// +//******************************************************************************** +// ASSIGNMENT +//******************************************************************************** +// +CAMrange& CAMrange::operator =( const CAMrange& A) +{ + base = A.base; + bound = A.bound; + stride = A.stride; + singleArgumentFlag = A.singleArgumentFlag; + underscoreFlag = A.underscoreFlag; + nullFlag = A.nullFlag; + return *this; +} + +// +//******************************************************************************** +// OUTPUT +//******************************************************************************** +// +ostream& operator <<(ostream& out_stream, const CAMrange& A) +{ +// +// Default Output : Memberwise Output +// + out_stream << "base = " << A.base + << " bound = " << A.bound + << " stride = " << A.stride << '\n'; + return(out_stream); +} +// +//******************************************************************************** +// MEMBER_FUNCTIONS +//******************************************************************************** +// + +void CAMrange::initialize() +{ + base = 0; + bound = 0; + stride = 0; + singleArgumentFlag = 0; + underscoreFlag = 0; + nullFlag = 1; +} + +void CAMrange::initialize(const CAMrange& R) +{ + base = R.base; + bound = R.bound; + stride = R.stride; + singleArgumentFlag = R.singleArgumentFlag; + underscoreFlag = R.underscoreFlag; + nullFlag = R.nullFlag; +} + +void CAMrange::initialize(long inputSize) +{ + base = 1; + bound = inputSize; + stride = 1; + singleArgumentFlag = 1; + underscoreFlag = 0; + nullFlag = 0; + CAMrange::CAMrangeError(*this); +} + +void CAMrange::initialize(long inputBase, long inputBound) +{ + base = inputBase; + bound = inputBound; + stride = 1; + singleArgumentFlag = 0; + underscoreFlag = 0; + nullFlag = 0; + CAMrange::CAMrangeError(*this); +} + +void CAMrange::initialize(long inputBase, long inputBound, long inputStride) +{ + base = inputBase; + bound = inputBound; + stride = inputStride; + singleArgumentFlag = 0; + underscoreFlag = 0; + nullFlag = 0; + CAMrange::CAMrangeError(*this); +} +CAMrange CAMrange::operator ++ (int) +{ + if(nullFlag != 1) + { + base = base + 1; + bound = bound + 1; + } + return *this; +} + +CAMrange CAMrange::operator -- (int) +{ + if(nullFlag != 1) + { + base = base - 1; + bound = bound - 1; + } + return *this; +} + +CAMrange CAMrange::operator + (long i) +{ + CAMrange R; + if(nullFlag != 1) + {R.initialize(base + i, bound + i, stride);} + + return R; +} + +CAMrange CAMrange::operator - (long i) +{ + CAMrange R; + if(nullFlag != 1) + {R.initialize(base - i, bound - i, stride);} + + return R; +} + +CAMrange operator + (long i, CAMrange& A) +{ + CAMrange R; + if(A.nullFlag != 1) + {R.initialize(A.base + i, A.bound + i, A.stride);} + + return R; +} + +void CAMrange::CAMrangeError(const CAMrange& A) +{ + if(((A.bound - A.base) + 1) < 0 ) + { + cerr <<"Error : Negative Number of Elements In Index Range " << endl; + CAMmvaExit(); + } + if(A.stride <= 0 ) + { + cerr <<"Error : Non Positive Stride in Index Range " << endl; + CAMmvaExit(); + } +} +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + + + diff --git a/src/matrix/range.h b/src/matrix/range.h new file mode 100755 index 0000000..189769d --- /dev/null +++ b/src/matrix/range.h @@ -0,0 +1,98 @@ +// +//****************************************************************************** +// RANGE.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Thu Oct 26 11:40:59 1995 +// +//******************************************************************************** +// + +#include + +#ifndef __CAMUNDERSCORE__ + class CAMunderscore; +#endif + +#ifndef __CAMRANGE__ +#define __CAMRANGE__ + +#include "mvaimpexp.h" // A + +class __IMPEXP__ CAMrange +{ + +protected : + + long base; + long bound; + long stride; + int singleArgumentFlag; + int underscoreFlag; + int nullFlag; + +public : + +// +// Constructors +// + CAMrange(); + CAMrange( const CAMrange& A); + CAMrange(long inputSize); + CAMrange(long inputBase, long inputBound); + CAMrange(long inputBase, long inputBound, long inputStride); + CAMrange(const CAMunderscore& A); +// +// Destructor +// + ~CAMrange(); +// +// Assignment +// + CAMrange& operator = ( const CAMrange& A); +// +// Output +// + __IMPEXP__ friend ostream& operator <<(ostream& out_stream, const CAMrange& A); +// +// initialize +// + void initialize(); + void initialize(const CAMrange& R); + void initialize(long inputSize); + void initialize(long inputBase, long inputBound); + void initialize(long inputBase, long inputBound, long inputStride); +// +// Public Member Functions +// + long getBase() const {return base;}; + long getBound() const {return bound;}; + long getCount() const {return long((bound - base)/stride + 1);}; + long getStride() const {return stride;}; + long length() const {return long((bound - base)/stride + 1);}; + int getUnderscoreFlag() const {return underscoreFlag;}; + int getNullFlag() const {return nullFlag;}; + int getSingleArgumentFlag() const {return singleArgumentFlag;}; + CAMrange operator ++ (int); + CAMrange operator -- (int); + CAMrange operator + (long i); + CAMrange operator - (long i); + friend CAMrange operator + (long i, CAMrange& A); + static void CAMrangeError(const CAMrange& A); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + diff --git a/src/matrix/rangetst1.cpp b/src/matrix/rangetst1.cpp new file mode 100755 index 0000000..3407056 --- /dev/null +++ b/src/matrix/rangetst1.cpp @@ -0,0 +1,47 @@ +// +//###################################################################### +// CAMrange Sample Program #1 +// +// Chris Andersion (C) UCLA 1997 8/18/97 +//###################################################################### +// +/* + This program demonstrates the use of CAMrange constructors and member + functions. +*/ +#include "access.h" +#include +#include +#include + +int main() +{ + cout << "CAMrange Object _(1,3) : " << _(1,3) << endl; + cout << endl; + + CAMrange R(-1,1); + + cout << "CAMrange Object R : " << R << endl; + cout << "CAMrange Object R+2 : " << R+2 << endl; + cout << "CAMrange Object R-2 : " << R-2 << endl; + cout << "CAMrange Object R++ : " << R++ << endl; + cout << "CAMrange Object R-- : " << R-- << endl; + cout << "R.getCount() = " << R.getCount() << endl; + cout << "R.length() = " << R.length() << endl; + + cout << endl; + + R.initialize(-2,2,2); + cout << "R.initialize(-2,2,2) : " << R << endl; + cout << "CAMrange Object R : " << R << endl; + cout << "CAMrange Object R-2 : " << R-2 << endl; + cout << "CAMrange Object R++ : " << R++ << endl; + cout << "CAMrange Object R-- : " << R-- << endl; + cout << "R.getCount() = " << R.getCount() << endl; + cout << "R.length() = " << R.length() << endl; + + cout << " Program End : Hit Any Key to Terminate " << endl; + getchar(); + return 0; +} + diff --git a/src/matrix/strctbse.cpp b/src/matrix/strctbse.cpp new file mode 100755 index 0000000..4115f56 --- /dev/null +++ b/src/matrix/strctbse.cpp @@ -0,0 +1,580 @@ +#include "strctbse.h" + +#undef __IMPEXP__ +#ifdef __BCPLUSPLUS__ +#ifdef __EXPORT_MVASUPPORT_B__ +#define __IMPEXP__ __export +#else +#define __IMPEXP__ +#endif +#else +#define __IMPEXP__ +#endif + +#ifdef __STATIC__ +#undef __IMPEXP__ +#define __IMPEXP__ +#endif +// +//***************************************************************** +// STRCTBSE.CPP +//***************************************************************** +// +// +//***************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Fri Sep 01 17:09:32 1995 +// +//***************************************************************** +// +// +//***************************************************************** +// CONSTRUCTORS +//***************************************************************** +// +// +//***************************************************************** +// +//***************************************************************** +// +CAMstructureBase::CAMstructureBase(): indexBegin(), indexEnd(), indexStride(), +indexBeginBase(), indexEndBase() +{ + dataDimension = 0; +} + +CAMstructureBase::CAMstructureBase(long dimension): indexBegin(dimension ), indexEnd(dimension), indexStride(dimension), +indexBeginBase(dimension), indexEndBase(dimension) +{ + dataDimension = dimension; +} +CAMstructureBase::CAMstructureBase( const CAMstructureBase& A) +{ + dataDimension = A.dataDimension; + indexBegin = A.indexBegin; + indexEnd = A.indexEnd; + indexStride = A.indexStride; + indexBeginBase = A.indexBeginBase; + indexEndBase = A.indexEndBase; +} +CAMstructureBase::CAMstructureBase(const CAMrange& R1, const CAMrange& R2 , + const CAMrange& R3 , const CAMrange&R4 , + const CAMrange& R5 , const CAMrange&R6 , + const CAMrange& R7) : indexBegin(), indexEnd(), indexStride(), +indexBeginBase(), indexEndBase() +{ + if(R1.getNullFlag() == 1) + { dataDimension = 0;} + else if(R2.getNullFlag() == 1) + {dataDimension = 1;} + else if(R3.getNullFlag() == 1) + {dataDimension = 2;} + else if(R4.getNullFlag() == 1) + {dataDimension = 3;} + else if(R5.getNullFlag() == 1) + {dataDimension = 4;} + else if(R6.getNullFlag() == 1) + {dataDimension = 5;} + else if(R7.getNullFlag() == 1) + {dataDimension = 6;} + else + {dataDimension = 7;} + + indexBegin.initialize(dataDimension); + indexEnd.initialize(dataDimension); + indexStride.initialize(dataDimension); + indexBeginBase.initialize(dataDimension); + indexEndBase.initialize(dataDimension); + + const CAMrange* RangeInput[7]; + RangeInput[0] = &R1; + RangeInput[1] = &R2; + RangeInput[2] = &R3; + RangeInput[3] = &R4; + RangeInput[4] = &R5; + RangeInput[5] = &R6; + RangeInput[6] = &R7; + + int i; + for(i = 0; i < dataDimension; i++) + { + indexBegin[i] = RangeInput[i]->getBase(); + indexEnd[i] = RangeInput[i]->getBound(); + indexStride[i] = RangeInput[i]->getStride(); + indexBeginBase[i] = indexBegin[i]; + indexEndBase[i] = indexEnd[i]; + } +} +// +//***************************************************************** +// DESTRUCTOR +//***************************************************************** +// +CAMstructureBase::~CAMstructureBase() +{ +} + +// +//***************************************************************** +// OUTPUT +//***************************************************************** +// +ostream& operator <<(ostream& out_stream, const CAMstructureBase& A) +{ + int i; + out_stream << "Structure Dimension = " << A.dataDimension << '\n'; + + out_stream << "indexBegin = "; + for(i = 0; i < A.dataDimension; i++) + out_stream << " " << A.indexBegin[i]; + out_stream << '\n'; + + out_stream << "indexEnd = "; + for(i = 0; i < A.dataDimension; i++) + out_stream << " " << A.indexEnd[i]; + out_stream << '\n'; + + out_stream << "indexStride = "; + for(i = 0; i < A.dataDimension; i++) + out_stream << " " << A.indexStride[i]; + out_stream << '\n'; + + out_stream << "indexBeginBase = "; + for(i = 0; i < A.dataDimension; i++) + out_stream << " " << A.indexBeginBase[i]; + out_stream << '\n'; + + out_stream << "indexEndBase = "; + for(i = 0; i < A.dataDimension; i++) + out_stream << " " << A.indexEndBase[i]; + out_stream << '\n'; + + + return(out_stream); +} + +// +//***************************************************************** +// ASSIGNMENT +//***************************************************************** +// +CAMstructureBase& CAMstructureBase::operator =( const CAMstructureBase& A) +{ + dataDimension = A.dataDimension; + indexBegin = A.indexBegin; + indexEnd = A.indexEnd; + indexStride = A.indexStride; + indexBeginBase = A.indexBeginBase; + indexEndBase = A.indexEndBase; + return *this; +} + +// +//***************************************************************** +// MEMBER_FUNCTIONS +//***************************************************************** +// + +void CAMstructureBase::initialize() +{ + indexBegin.initialize(); + indexEnd.initialize(); + indexStride.initialize(); + indexBeginBase.initialize(); + indexEndBase.initialize(); + dataDimension = 0; +} + + +void CAMstructureBase::initialize(long dimension) +{ + indexBegin.initialize(dimension); + indexEnd.initialize(dimension); + indexStride.initialize(dimension); + indexBeginBase.initialize(dimension); + indexEndBase.initialize(dimension); + dataDimension = dimension; +} + +void CAMstructureBase::initialize(const CAMstructureBase& A) +{ + dataDimension = A.dataDimension; + indexBegin.initialize(A.indexBegin); + indexEnd.initialize(A.indexEnd); + indexStride.initialize(A.indexStride); + indexBeginBase.initialize(A.indexBeginBase); + indexEndBase.initialize(A.indexEndBase); +} +void CAMstructureBase::initialize(const CAMrange& R1, const CAMrange& R2, + const CAMrange& R3, const CAMrange&R4, const CAMrange& R5, + const CAMrange&R6, const CAMrange& R7) +{ + if(R1.getNullFlag() == 1){dataDimension = 0;} + else if(R2.getNullFlag() == 1){dataDimension = 1;} + else if(R3.getNullFlag() == 1){dataDimension = 2;} + else if(R4.getNullFlag() == 1){dataDimension = 3;} + else if(R5.getNullFlag() == 1){dataDimension = 4;} + else if(R6.getNullFlag() == 1){dataDimension = 5;} + else if(R7.getNullFlag() == 1){dataDimension = 6;} + else {dataDimension = 7;} + + indexBegin.initialize(dataDimension); + indexEnd.initialize(dataDimension); + indexStride.initialize(dataDimension); + indexBeginBase.initialize(dataDimension); + indexEndBase.initialize(dataDimension); + + const CAMrange* RangeInput[7]; + RangeInput[0] = &R1; + RangeInput[1] = &R2; + RangeInput[2] = &R3; + RangeInput[3] = &R4; + RangeInput[4] = &R5; + RangeInput[5] = &R6; + RangeInput[6] = &R7; + + int i; + for(i = 0; i < dataDimension; i++) + { + indexBegin[i] = RangeInput[i]->getBase(); + indexEnd[i] = RangeInput[i]->getBound(); + indexStride[i] = RangeInput[i]->getStride(); + indexBeginBase[i] = indexBegin[i]; + indexEndBase[i] = indexEnd[i]; + } +} +// +//***************************************************************** +// MEMBER_FUNCTIONS +//***************************************************************** +// +int CAMstructureBase::isConformingTo(const CAMstructureBase& A) const +{ + int returnValue = 0; + + long loopDimension; + long AloopDimension; + + MVAlongBase Count(dataDimension); + MVAlongBase ACount(A.dataDimension); + long i, ii; + + for(i = 0; i < dataDimension; i++) + Count[i] = (( indexEnd[i] - indexBegin[i])/ indexStride[i]) + 1; + + ii = 0; + for(i = 0; i < dataDimension; i++) + { if(Count[i] != 1) {Count[ii] = Count[i]; ii++;} } + + loopDimension = ii; + if(loopDimension == 0) loopDimension = 1; + + + for(i = 0; i < A.dataDimension; i++) + ACount[i] = ((A.indexEnd[i] - A.indexBegin[i])/A.indexStride[i]) + 1; + + ii = 0; + for(i = 0; i < A.dataDimension; i++) + { if(ACount[i] != 1) {ACount[ii] = ACount[i]; ii++;} } + + AloopDimension = ii; + if(AloopDimension == 0) AloopDimension = 1; + + if(loopDimension == AloopDimension) + { + returnValue = 1; + for(i =0; i< loopDimension; i++) + if(ACount[i] != Count[i]) returnValue =0; + } + + return returnValue; +} + +int CAMstructureBase::isStrictConformingTo(const CAMstructureBase& A) const +{ + int returnValue = 0; + + MVAlongBase Count(dataDimension); + MVAlongBase ACount(A.dataDimension); + long i; + + for(i = 0; i < dataDimension; i++) + Count[i] = (( indexEnd[i] - indexBegin[i])/ indexStride[i]) + 1; + + for(i = 0; i < A.dataDimension; i++) + ACount[i] = ((A.indexEnd[i] - A.indexBegin[i])/A.indexStride[i]) + 1; + + if(dataDimension == A.dataDimension) + { + returnValue = 1; + for(i =0; i< dataDimension; i++) + if(ACount[i] != Count[i]) returnValue =0; + } + + return returnValue; +} + +int CAMstructureBase::isMatrixOpConformingTo(const CAMstructureBase& A) const +{ + if((dataDimension !=2)||(A.dataDimension !=2)) return 0; + + int returnValue = 0; + + long Count2 = (( indexEnd[1] - indexBegin[1])/ indexStride[1]) + 1; + long ACount1 = ((A.indexEnd[0] - A.indexBegin[0])/A.indexStride[0]) + 1; + + if(Count2 == ACount1) returnValue = 1; + + return returnValue; +} + +int CAMstructureBase::isSubset() const +{ +// +// Returns 1 if invoking instance is a subset of it structure +// + int returnValue = 0; + for(int i = 0; i < dataDimension; i++) + returnValue += (indexEndBase[i] - indexEnd[i]) + + (indexBegin[i] - indexBeginBase[i]) + + (indexStride[i] - 1); + if(returnValue > 0) returnValue = 1; + return returnValue; + +} +void CAMstructureBase::getNormalizedLoops(long& loopDimension, long& Offset, MVAlongBase& Count, MVAlongBase& Stride) const +{ + MVAlongBase localCount(dataDimension); + MVAlongBase localStride(dataDimension); + + + long i; long M; long i_new; + + for(i = 0; i < dataDimension; i++) + localCount[i] = ((indexEnd[i] - indexBegin[i])/indexStride[i]) + 1; + + M = 1; + Offset = (indexBegin[0] - indexBeginBase[0])*M; + localStride[0] = indexStride[0]; + + for(i = 1; i < dataDimension; i++) + { + M = M*((indexEndBase[i-1] - indexBeginBase[i-1]) + 1); + localStride[i] = indexStride[i]*M; + Offset += (indexBegin[i] - indexBeginBase[i])*M; + } +// +// Collapse loops +// + i_new = 0; + for(i = 0; i < dataDimension; i++) + { + if(localCount[i] != 1) + { + localCount[i_new] = localCount[i]; + localStride[i_new] = localStride[i]; + i_new++; + } + } + + loopDimension = i_new; + if(loopDimension == 0) loopDimension = 1; + + Count.initialize(loopDimension); + Stride.initialize(loopDimension); + for(i = 0; i < loopDimension; i++) + { + Count[i] = localCount[i]; + Stride[i] = localStride[i]; + } + +} + +void CAMstructureBase::setStructureSubset(const CAMrange& R1, const CAMrange& R2 , + const CAMrange& R3 , const CAMrange&R4 , + const CAMrange& R5 , const CAMrange&R6 , + const CAMrange& R7) +{ + const CAMrange* RangeInput[7]; + RangeInput[0] = &R1; + RangeInput[1] = &R2; + RangeInput[2] = &R3; + RangeInput[3] = &R4; + RangeInput[4] = &R5; + RangeInput[5] = &R6; + RangeInput[6] = &R7; + + int i; + for(i = 0; i < dataDimension; i++) + { + if(RangeInput[i]->getUnderscoreFlag() == 1) + {indexStride[i] = 1;} + else if(RangeInput[i]->getSingleArgumentFlag() == 1) + { + indexBegin[i] = RangeInput[i]->getBound(); + indexEnd[i] = RangeInput[i]->getBound(); + + indexStride[i] = 1; + /*** + Change 01/29/97 was + indexStride[i] = RangeInput[i]->getBound(); + ****/ + } + else + { + indexBegin[i] = RangeInput[i]->getBase(); + indexEnd[i] = RangeInput[i]->getBound(); + indexStride[i] = RangeInput[i]->getStride(); + } + } + return; + +} + +long CAMstructureBase::getFullDataCount() const +{ + if(dataDimension == 0) return 0; + + long fullDataCount = 1; + for(long i = 0; i < dataDimension; i++) + { fullDataCount *= (indexEndBase[i] - indexBeginBase[i]) + 1;} + return fullDataCount; +} +long CAMstructureBase::getDataCount() const +{ + if(dataDimension == 0) return 0; + + long dataCount = 1; + for(long i = 0; i < dataDimension; i++) + { dataCount *= ((indexEnd[i] - indexBegin[i])/indexStride[i]) + 1;} + return dataCount; +} +void CAMstructureBase::initializeMinStructure(CAMstructureBase& A) const +{ + A.dataDimension = dataDimension; + A.indexBegin.initialize(indexBegin); + A.indexEnd.initialize(dataDimension); + A.indexBeginBase.initialize(indexBegin); + A.indexEndBase.initialize(dataDimension); + A.indexStride.initialize(dataDimension); + + for(long i = 0; i < dataDimension; i++) + { + A.indexEnd[i] = A.indexBegin[i] + ((indexEnd[i] - indexBegin[i])/indexStride[i]); + A.indexEndBase[i] = A.indexEnd[i]; + A.indexStride[i] = 1; + } +} +// +//***************************************************************** +// Coordinate Index Handling +//***************************************************************** +// +long CAMstructureBase::exchangeReferenceIndex(long i) +{ + static long index = 1; + long index_return = index; // take current value + index = i; // give input value + return index_return ; +} + +CAMstructureBase& CAMstructureBase::operator[](long i) +{ + if((i < 0)||(i > dataDimension)) + {CAMstructureBase::illegalDimension(i, dataDimension);} + CAMstructureBase::exchangeReferenceIndex(i); + + return *this; +} + +const CAMstructureBase& CAMstructureBase::operator[](long i) const +{ + if((i < 0)||(i > dataDimension)) + {CAMstructureBase::illegalDimension(i, dataDimension);} + CAMstructureBase::exchangeReferenceIndex(i); + return *this; +} + +long CAMstructureBase::getIndexBase() const +{ + long index = CAMstructureBase::exchangeReferenceIndex(1); + return indexBegin[index - 1]; +} + +long CAMstructureBase::getIndexBaseBase() const +{ + long index = CAMstructureBase::exchangeReferenceIndex(1); + return indexBeginBase[index - 1]; +} + +long CAMstructureBase::getIndexBound() const +{ + long index = CAMstructureBase::exchangeReferenceIndex(1); + return indexEnd[index-1]; +} + + +long CAMstructureBase::getIndexStride() const +{ + long index = CAMstructureBase::exchangeReferenceIndex(1); + return indexStride[index - 1]; +} + +long CAMstructureBase::getIndexCount() const +{ + long index = CAMstructureBase::exchangeReferenceIndex(1); + return + ((indexEnd[index - 1] - indexBegin[index- 1])/indexStride[index -1]) + 1; +} + +void CAMstructureBase::setIndexBase(long i) +{ + long k = CAMstructureBase::exchangeReferenceIndex(1); + long offset = i - indexBegin[k]; + indexBegin[k] = indexBegin[k] + offset; + indexEnd[k] = indexEnd[k] + offset; + indexBeginBase[k] = indexBeginBase[k] + offset; + indexEndBase[k] = indexEndBase[k] + offset; +} + +void CAMstructureBase::setIndexStride(long i) +{ + long index = CAMstructureBase::exchangeReferenceIndex(1); + indexStride[index - 1] = i; +} + +void CAMstructureBase::setAllIndexBase(long i) +{ + long offset; + + for(long k = 0; k < dataDimension; k++) + { + offset = i - indexBegin[k]; + indexBegin[k] = indexBegin[k] + offset; + indexEnd[k] = indexEnd[k] + offset; + indexBeginBase[k] = indexBeginBase[k] + offset; + indexEndBase[k] = indexEndBase[k] + offset; + } +} +// +//***************************************************************** +// Error Handling +//***************************************************************** +// +void CAMstructureBase::illegalDimension(long i, long dimension) +{ + cerr << "Argument to Dimension Selection Out of Bounds " << '\n'; + cerr << "Argument Input : " << i << " Acceptable Range : " << + "(0, " << dimension << ")" << endl; + CAMmvaExit(); +} +// +//***************************************************************** +// CPP File End +//***************************************************************** +// + + + diff --git a/src/matrix/strctbse.h b/src/matrix/strctbse.h new file mode 100755 index 0000000..1816b5d --- /dev/null +++ b/src/matrix/strctbse.h @@ -0,0 +1,134 @@ +// +//****************************************************************************** +// STRCTBSE.H +//****************************************************************************** +// + +#include +#include "mvalngbase.h" +#include "access.h" +#include "mvaexit.h" + +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Thu Nov 02 13:33:24 1995 +// +//******************************************************************************** +// + +#ifndef __CAMSTRUCTUREBASE__ +#define __CAMSTRUCTUREBASE__ + +#include "mvaimpexp.h" // B +// +// +// +//extern CAMrange __IMPEXP__ CAMnullRange; +// +// +// + +class __IMPEXP__ CAMstructureBase +{ +// +// +// + friend class CAMstructureBaseTest; +// +// +// + +public : + + int dataDimension; + MVAlongBase indexBegin; + MVAlongBase indexEnd; + MVAlongBase indexStride; + MVAlongBase indexBeginBase; + MVAlongBase indexEndBase; + +public : + + CAMstructureBase(); + CAMstructureBase( const CAMstructureBase& A); + CAMstructureBase(long dimension); + CAMstructureBase(const CAMrange& R1, const CAMrange& R2 = CAMnullRange, + const CAMrange& R3 = CAMnullRange, const CAMrange&R4 = CAMnullRange, + const CAMrange& R5 = CAMnullRange, const CAMrange&R6 = CAMnullRange, + const CAMrange& R7 = CAMnullRange); +// +// Destructor +// + ~CAMstructureBase(); +// +// Output +// + __IMPEXP__ friend ostream& operator <<(ostream& out_stream, const CAMstructureBase& A); +// +// Assignment +// + CAMstructureBase& operator = ( const CAMstructureBase& A); +// +// Initialization +// + void initialize(); + void initialize(long dimension); + void initialize(const CAMstructureBase& A); + void initialize(const CAMrange& R1, const CAMrange& R2 = CAMnullRange, + const CAMrange& R3 = CAMnullRange, const CAMrange&R4 = CAMnullRange, + const CAMrange& R5 = CAMnullRange, const CAMrange&R6 = CAMnullRange, + const CAMrange& R7 = CAMnullRange); +// +// +// + int getDimension()const {return dataDimension;}; + const CAMstructureBase& operator[](long i) const; + CAMstructureBase& operator[](long i); + long getIndexBase() const; + long getIndexBound() const; + long getIndexStride() const; + long getIndexCount() const; + long getIndexBaseBase() const; + void setIndexBase(long i); + void setIndexStride(long i); + void setAllIndexBase(long i); + static long exchangeReferenceIndex(long i); +// +// +// + long getFullDataCount()const; + long getDataCount()const; + int isSubset() const; + int isConformingTo(const CAMstructureBase& A) const; + int isStrictConformingTo(const CAMstructureBase& A) const; + int isMatrixOpConformingTo(const CAMstructureBase& A) const; + void getNormalizedLoops(long& loopDimension, long& Offset, MVAlongBase& Count, MVAlongBase& Stride) const; + void initializeMinStructure(CAMstructureBase& A) const; + void setStructureSubset(const CAMrange& R1, const CAMrange& R2 = CAMnullRange, + const CAMrange& R3 = CAMnullRange, const CAMrange&R4 = CAMnullRange, + const CAMrange& R5 = CAMnullRange, const CAMrange&R6 = CAMnullRange, + const CAMrange& R7 = CAMnullRange); +// +// error handling +// + static void illegalDimension(long i, long dimension); + static void needToSelectDimension(); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + + + + + diff --git a/src/matrix/typehndl.h b/src/matrix/typehndl.h new file mode 100755 index 0000000..6071148 --- /dev/null +++ b/src/matrix/typehndl.h @@ -0,0 +1,268 @@ +// +//****************************************************************************** +// TYPEHNDL.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Tue Oct 17 21:17:10 1995 +// +//******************************************************************************** +// +// +// +// +#ifndef __NO_COMPLEX__ +#include +#endif +// +// +// + +#include "camtype.h" +#include "iostream.h" + + +#ifndef __CAMTYPEHANDLER__ +#define __CAMTYPEHANDLER__ + +#undef __IMPEXP__ +#ifdef __BCPLUSPLUS__ +#ifdef __EXPORT_MVASUPPORT_B__ +#define __IMPEXP__ __export +#else +#define __IMPEXP__ __import +#endif +#else +#define __IMPEXP__ +#endif + +#ifdef __STATIC__ +#undef __IMPEXP__ +#define __IMPEXP__ +#endif + + +class __IMPEXP__ CAMTypeHandler +{ + +protected : + + int dType; + void* dP; + +public : + +// +// constructors +// + CAMTypeHandler() {dType = 0; dP = 0;}; + CAMTypeHandler(const CAMTypeHandler& T) + { + dType = T.dType; + switch (dType) + { + case CAMType::typeNull: dP = 0; break; + case CAMType::typeInt : + dP = new int[1]; *((int*)dP) = *((int*)T.dP); break; + case CAMType::typeLong : + dP = new long[1]; *((long*)dP) = *((long*)T.dP); break; + case CAMType::typeFloat : + dP = new float[1]; *((float*)dP) = *((float*)T.dP); break; + case CAMType::typeDouble : + dP = new double[1]; *((double*)dP) = *((double*)T.dP); break; +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + dP = new complex[1]; *((complex*)dP) = *((complex*)T.dP); break; +#endif + } + }; + CAMTypeHandler(int i) + {dType = CAMType::typeInt; dP= new int[1]; *((int*)dP) = i;}; + CAMTypeHandler(long l) + {dType = CAMType::typeLong; dP= new long[1]; *((long*)dP) = l;}; + CAMTypeHandler(float f) + {dType = CAMType::typeFloat; dP= new float[1]; *((float*)dP) = f;}; + CAMTypeHandler(double d) + {dType = CAMType::typeDouble; dP= new double[1]; *((double*)dP) = d;}; +#ifndef __NO_COMPLEX__ + CAMTypeHandler(complex c) + {dType = CAMType::typeComplex; dP= new complex[1]; *((complex*)dP) = c;}; +#endif + virtual ~CAMTypeHandler() + { + dPDelete(); + }; + + /*! \brief Deletes the data pointer + * \detail Determines the type that the void* pointer points to, then reinterpret_cast to delete. + */ + void dPDelete() + { + if(dP != 0) + { + if(dType == CAMType::typeInt) + delete reinterpret_cast(dP); + else if(dType == CAMType::typeLong) + delete reinterpret_cast(dP); + else if(dType == CAMType::typeFloat) + delete reinterpret_cast(dP); + else if(dType == CAMType::typeDouble) + delete reinterpret_cast(dP); + #ifndef __NO_COMPLEX__ + else if(dType == CAMType::typeComplex) + delete reinterpret_cast(dP); + #endif + } + }; + +// +// Assignment +// + void operator = (CAMTypeHandler & T) + { + dPDelete(); + switch (T.dType) + { + case CAMType::typeNull: dP = 0; break; + case CAMType::typeInt : + dP = new int[1]; *((int*)dP) = *((int*)T.dP); break; + case CAMType::typeLong : + dP = new long[1]; *((long*)dP) = *((long*)T.dP); break; + case CAMType::typeFloat : + dP = new float[1]; *((float*)dP) = *((float*)T.dP); break; + case CAMType::typeDouble : + dP = new double[1]; *((double*)dP) = *((double*)T.dP); break; +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + dP = new complex[1]; *((complex*)dP) = *((complex*)T.dP); break; +#endif + } + }; + void operator = (int i) + {dPDelete(); dType = CAMType::typeInt; dP= new int[1]; *((int*)dP) = i;}; + void operator = (long l) + {dPDelete(); dType = CAMType::typeLong; dP= new long[1]; *((long*)dP) = l;}; + void operator = (float f) + {dPDelete(); dType = CAMType::typeFloat; dP= new float[1]; *((float*)dP) = f;}; + void operator = (double d) + {dPDelete(); dType = CAMType::typeDouble; dP= new double[1]; *((double*)dP) = d;}; +#ifndef __NO_COMPLEX__ + void operator = (complex c) + {dPDelete(); dType = CAMType::typeComplex; dP= new complex[1]; *((complex*)dP) = c;}; +#endif +// +// output +// + friend ostream& operator <<(ostream& out_stream, const CAMTypeHandler& A) +{ switch (A.dType) + { + case CAMType::typeNull: break; + case CAMType::typeInt : + out_stream << *((int*)A.dP); break; + case CAMType::typeLong : + out_stream << *((long*)A.dP); break; + case CAMType::typeFloat : + out_stream << *((float*)A.dP); break; + case CAMType::typeDouble : + out_stream << *((double*)A.dP); break; +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : + out_stream << *((complex*)A.dP); break; +#endif + } + return out_stream; +}; +// +// Conversions +// + operator int() + { + int r; + switch (dType) + { + case CAMType::typeInt : r = *((int*)dP); break; + case CAMType::typeLong : r = int(*((long*)dP)); break; + case CAMType::typeFloat : r = int(*((float*)dP)); break; + case CAMType::typeDouble : r = int(*((double*)dP)); break; +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : r = int(real(*((complex*)dP))); break; +#endif + } + return r; + }; + operator long() + { + long r; + switch (dType) + { + case CAMType::typeInt : r = long(*((int*)dP)); break; + case CAMType::typeLong : r = (*((long*)dP)); break; + case CAMType::typeFloat : r = long(*((float*)dP)); break; + case CAMType::typeDouble : r = long(*((double*)dP)); break; +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : r = long(real(*((complex*)dP))); break; +#endif + } + return r; + }; + operator float() + { + float r; + switch (dType) + { + case CAMType::typeInt : r = float(*((int*)dP)); break; + case CAMType::typeLong : r = float(*((long*)dP)); break; + case CAMType::typeFloat : r = (*((float*)dP)); break; + case CAMType::typeDouble : r = float(*((double*)dP)); break; +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : r = float(real(*((complex*)dP))); break; +#endif + } + return r; + }; + operator double() + { + double r; + switch (dType) + { + case CAMType::typeInt : r = double(*((int*)dP)); break; + case CAMType::typeLong : r = double(*((long*)dP)); break; + case CAMType::typeFloat : r = double(*((float*)dP)); break; + case CAMType::typeDouble : r = (*((double*)dP)); break; +#ifndef __NO_COMPLEX__ + case CAMType::typeComplex : r = double(real(*((complex*)dP))); break; +#endif + } + return r; + }; +#ifndef __NO_COMPLEX__ + operator complex() + { + complex r; + switch (dType) + { + case CAMType::typeInt : r = complex(*((int*)dP)); break; + case CAMType::typeLong : r = complex(*((long*)dP)); break; + case CAMType::typeFloat : r = complex(*((float*)dP)); break; + case CAMType::typeDouble : r = complex(*((double*)dP)); break; + case CAMType::typeComplex : r = (*((complex*)dP)); break; + } + return r; + }; +#endif + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + diff --git a/src/matrix/under.cpp b/src/matrix/under.cpp new file mode 100755 index 0000000..031ae64 --- /dev/null +++ b/src/matrix/under.cpp @@ -0,0 +1,44 @@ +#include "under.h" +// +//****************************************************************************** +// UNDER.CPP +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Fri Sep 01 17:52:03 1995 +// +//******************************************************************************** +// +// Defintion of _ as an instance of the CAMunderscore class +// +//CAMunderscore __IMPEXP__ _; +// +// Constructors +// +CAMunderscore::CAMunderscore(){}; +// +// destructor +// +CAMunderscore::~CAMunderscore(){}; +// +// Public Member Functions +// +CAMrange CAMunderscore::operator()(long inputSize) + {return CAMrange(inputSize);}; +CAMrange CAMunderscore::operator()(long inputBase, long inputBound) + {return CAMrange(inputBase, inputBound);}; +CAMrange CAMunderscore::operator()(long inputBase, long inputBound, long inputStride) + {return CAMrange(inputBase, inputBound, inputStride);}; +// +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + + + diff --git a/src/matrix/under.h b/src/matrix/under.h new file mode 100755 index 0000000..59746c8 --- /dev/null +++ b/src/matrix/under.h @@ -0,0 +1,54 @@ +// +//****************************************************************************** +// UNDER.H +//****************************************************************************** +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA 1995 +// +// Mon Sep 25 11:52:15 1995 +// +//******************************************************************************** +// + +#include "range.h" + + +#ifndef __CAMUNDERSCORE__ +#define __CAMUNDERSCORE__ + +#include "mvaimpexp.h" + +class __IMPEXP__ CAMunderscore +{ + +public : + +// +// Constructors +// + CAMunderscore(); +// +// destructor +// + ~CAMunderscore(); +// +// Public Member Functions +// + CAMrange operator()(long inputSize); + CAMrange operator()(long inputBase, long inputBound); + CAMrange operator()(long inputBase, long inputBound, long inputStride); + +}; +#endif +// +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + + + diff --git a/src/matrix/vecbse.cpp b/src/matrix/vecbse.cpp new file mode 100755 index 0000000..1ed00af --- /dev/null +++ b/src/matrix/vecbse.cpp @@ -0,0 +1,1280 @@ +#include "arraybse.h" +#include "vecbse.h" +#include "matbse.h" +#include "matbse.h" +#include "bnengine.h" +#include "matbse.h" +#include "blas.h" +// +//*************************************************************** +// VECBSE.CPP +//*************************************************************** +// +// +//***************************************************************** +// +// Chris Anderson +// +// Mon Sep 11 12:49:20 1995 +// +//***************************************************************** +// +// +//***************************************************************** +// CONSTRUCTORS +//***************************************************************** +// +// +//***************************************************************** +// +//***************************************************************** +// +CAMvectorBase::CAMvectorBase() +: Structure() +{ + DataP = 0; + typeValue = 0; + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +CAMvectorBase::CAMvectorBase(int d_type) +: Structure() +{ + DataP = 0; + typeValue = d_type; + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +CAMvectorBase::CAMvectorBase(const CAMvectorBase& A) +:Structure(A.Structure) +{ + if(A.DataP == 0) + {DataP = 0;} + else + { + if(A.referenceFlag == 1) + {DataP = A.DataP; } + else if(A.DataP->getTemporaryFlag() == 1) + { + DataP = new CAMdataHandler(*(A.DataP)); + DataP ->setReferenceCount(1); + } + else + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); + // + // copy based on type + // + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); + // + // + // + } + } + typeValue = A.typeValue; + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +CAMvectorBase::CAMvectorBase(int d_type, const CAMrange& R1) +:Structure() +{ + Structure.initialize(R1,_(R1.getBase(),R1.getBase())); + DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type); + DataP->setReferenceCount(1); + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +// +//***************************************************************** +// DESTRUCTOR +//***************************************************************** +// +CAMvectorBase::~CAMvectorBase() +{ + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() < 0) + { + cerr << " Error : Reference Count < 0" << endl; + } + if(DataP->getReferenceCount() == 0) delete DataP; + } +} +void CAMvectorBase::operator =(double value) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + Structure.initialize(_(1,1),_(1,1)); + DataP = new CAMdataHandler(1,CAMType::typeDouble); + DataP->setReferenceCount(1); + referenceFlag = 0; + vectorBaseReferenceCount = 0; + } + else + { + CAMstructureBase AStructure(_(1,1),_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,AStructure);} + } + + CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value); +} +void CAMvectorBase::operator =( const CAMvectorBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),typeValue); + DataP->setReferenceCount(1); + typeValue = CAMType::typeDouble; + referenceFlag = 0; + vectorBaseReferenceCount = 0; + } + else + { + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} + } + + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMvectorBase::operator =( const CAMmatrixBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP == 0) + { + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),typeValue); + DataP->setReferenceCount(1); + typeValue = CAMType::typeDouble; + referenceFlag = 0; + vectorBaseReferenceCount = 0; + } + else + { + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} + } + + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); +} + +// +//******************************************************************************** +// OUTPUT +//******************************************************************************** +// +ostream& operator <<(ostream& out_stream, const CAMvectorBase& A) +{ + const long* beginPtr = A.Structure.indexBegin.getDataPointer(); + const long* endPtr = A.Structure.indexEnd.getDataPointer(); + const long* stridePtr = A.Structure.indexStride.getDataPointer(); + + int saveWidth=out_stream.width(); + double OutValue; + + long i1, i2; + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + for(i2 = *(beginPtr+1); i2 <= *(endPtr +1); i2 += *(stridePtr+1)) + { + + out_stream.width(saveWidth); + OutValue =*((double*)A.getDataPointer(i1,i2)); + if(OutValue < 0 ) + out_stream << OutValue <<" "; + else + out_stream << " " << OutValue <<" "; + } + out_stream << endl; + } + return(out_stream); +} + +istream& operator >>(istream& in_stream, CAMvectorBase& A) +{ + const long* beginPtr = A.Structure.indexBegin.getDataPointer(); + const long* endPtr = A.Structure.indexEnd.getDataPointer(); + const long* stridePtr = A.Structure.indexStride.getDataPointer(); + + long i1, i2; + + for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr) + { + for(i2 = *(beginPtr+1); i2 <= *(endPtr +1); i2 += *(stridePtr+1)) + { + if( !( in_stream >> *((double*)A.getDataPointer(i1,i2)))) + CAMarrayBase::inputSizeError(); + }} + return(in_stream); +} + +// +//***************************************************************** +// INITIALIZATION MEMBER_FUNCTIONS +//***************************************************************** +// + +void CAMvectorBase::initialize() +{ + Structure.initialize(); + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + DataP = 0; + typeValue = 0; + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +void CAMvectorBase::initialize(int d_type) +{ + Structure.initialize(); + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + DataP = 0; + typeValue = d_type; + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +void CAMvectorBase::initialize(const CAMvectorBase& A) +{ +// +// NEED CONVERSION CHECK +// + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + if(A.DataP != 0) + { + A.Structure.initializeMinStructure(Structure); + + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); + CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP); + } + else + { + DataP = 0; + Structure.initialize(); + } + + typeValue = A.typeValue; + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +void CAMvectorBase::initialize(int d_type, const CAMrange& R1) +{ + Structure.initialize(R1,_(R1.getBase(),R1.getBase())); + + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type); + DataP->setReferenceCount(1); + referenceFlag = 0; + vectorBaseReferenceCount = 0; +} + +// +//*************************************************************** +// ARRAYOPS.CPP +//*************************************************************** +// +// +//***************************************************************** +// +void CAMvectorBase::initializeReturnArgument(const CAMvectorBase& A) +{ + A.Structure.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType()); + DataP->setReferenceCount(1); +} +void CAMvectorBase::initializeReturnArgument(const CAMstructureBase& S, int dataT) +{ + S.initializeMinStructure(Structure); + DataP = new CAMdataHandler(Structure.getFullDataCount(), dataT); + DataP->setReferenceCount(1); +} +void CAMvectorBase::initializeMinDuplicate(const CAMvectorBase& A) +{ + + if(A.DataP == 0) return; + + long i; + long icount = 0; + long dimension = 0; + + for(i = 1; i <= A.Structure.getDimension(); i++) + if(A.Structure[i].getIndexCount() != 1) dimension++; + + + if(dimension == 0) dimension = 1; + Structure.initialize(dimension); + + + for(i = 1; i <= A.Structure.getDimension(); i++) + { + if(A.Structure[i].getIndexCount() != 1) + { + Structure.indexBegin[icount] = 1; + Structure.indexBeginBase[icount] = 1; + Structure.indexEndBase[icount] = A.Structure[i].getIndexCount(); + Structure.indexEnd[icount] = A.Structure[i].getIndexCount(); + Structure.indexStride[icount] = 1; + icount++; + } + } + + if(icount == 0) + { + Structure.indexBegin[icount] = 1; + Structure.indexBeginBase[icount] = 1; + Structure.indexEndBase[icount] = 1; + Structure.indexEnd[icount] = 1; + Structure.indexStride[icount] = 1; + } + DataP = new CAMdataHandler(Structure.getFullDataCount(), A.typeValue); + DataP->setReferenceCount(1); +// +// copy over data +// + *this = A; +} +// +//***************************************************************** +// Operators +//***************************************************************** +// +CAMvectorBase CAMvectorBase::operator-() const +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S; + S.initializeReturnArgument(*this); + + CAMbinaryEngine::doubleAequalToMinusB(S.Structure, *S.DataP, Structure, *DataP); + S.setTemporaryFlag(); + return S; +} + +CAMvectorBase CAMvectorBase::operator+(const CAMvectorBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMvectorBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMvectorBase::operator+(const CAMmatrixBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMvectorBase CAMvectorBase::operator-(const CAMvectorBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMvectorBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAminusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} +CAMmatrixBase CAMvectorBase::operator-(const CAMmatrixBase& A) const +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + CAMmatrixBase S; + S.initializeReturnArgument(A.Structure,A.DataP->getDataType()); + + CAMbinaryEngine::doubleCequalAminusB(Structure, *DataP, A.Structure, *A.DataP, + S.Structure, *S.DataP); + + S.setTemporaryFlag(); + return S; +} + +CAMmatrixBase CAMvectorBase::operator*(const CAMvectorBase& A) const +{ + if(Structure.isMatrixOpConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// +// +// Prepare Operands +// + int STempFlag = 0; + int TTempFlag = 0; + + CAMvectorBase* S; + CAMvectorBase* T; + + if(Structure.isSubset() == 0) + { S = (CAMvectorBase*)this;} + else + { + STempFlag = 1; + S = new CAMvectorBase(); + S->initializeReturnArgument(*this); + *S = *this; + } + + if(A.Structure.isSubset() == 0) + { T = (CAMvectorBase*)&A;} + else + { + TTempFlag = 1; + T = new CAMvectorBase(); + T->initializeReturnArgument(A); + *T = A; + } +// +// return argument +// + long Rows = (*S).Structure[1].getIndexCount(); + long Cols = A.Structure[2].getIndexCount(); + + CAMrange R1((*S).Structure[1].getIndexBase(), + (*S).Structure[1].getIndexBase() + Rows - 1); + + CAMrange R2(A.Structure[2].getIndexBase(), + A.Structure[2].getIndexBase() + Cols - 1); + + CAMmatrixBase R(CAMType::typeDouble,R1, R2); +// +// dgemm performs the operation R := alpha*op(S)*op(T) + beta*R; +// op(matrix) is either the matrix or its transpose. +// the characters transX below specify that S and T are 'n'ot +// to be transposed. +// +// R = m by n +// S = m by k +// T = k by n +// + char transa = 'n'; + char transb = 'n'; + + long m = R[1].getIndexCount(); + long n = R[2].getIndexCount(); + long k = (*S).Structure[2].getIndexCount(); + + double* s = (double*)((*S).getDataPointer()); + double* t = (double*)((*T).getDataPointer()); + double* r = (double*)( R.getDataPointer()); + + long lds = (*S).Structure[1].getIndexCount(); + long ldt = (*T).Structure[1].getIndexCount(); + long ldr = R[1].getIndexCount(); + + double alpha = 1.0; + double beta = 0.0; + + short f1 = 1; + short f2 = 1; + + dgemm_(&transa, &transb, &m, &n, &k, &alpha, s, &lds, t, &ldt, + &beta, r, &ldr,f1,f2); +// +// clean up +// + if(STempFlag == 1) delete S; + if(TTempFlag == 1) delete T; + + R.setTemporaryFlag(); + return R; +} + + + +CAMvectorBase CAMvectorBase::operator*(const CAMmatrixBase& A) const +{ + if(Structure.isMatrixOpConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// +// +// Prepare Operands +// + int STempFlag = 0; + int TTempFlag = 0; + + CAMvectorBase* S; + CAMmatrixBase* T; + + if(Structure.isSubset() == 0) + { S = (CAMvectorBase*)this;} + else + { + STempFlag = 1; + S = new CAMvectorBase(); + S->initializeReturnArgument(*this); + *S = *this; + } + + if(A.Structure.isSubset() == 0) + { T = (CAMmatrixBase*)&A;} + else + { + TTempFlag = 1; + T = new CAMmatrixBase(); + T->initializeReturnArgument(A); + *T = A; + } +// +// return argument +// + long Rows = (*S).Structure[1].getIndexCount(); + long Cols = A.Structure[2].getIndexCount(); + + CAMrange R1((*S).Structure[1].getIndexBase(), + (*S).Structure[1].getIndexBase() + Rows - 1); + + CAMrange R2(A.Structure[2].getIndexBase(), + A.Structure[2].getIndexBase() + Cols - 1); + + CAMvectorBase R; + if(R1.length() == 1) + {R.initialize(CAMType::typeDouble,R2);} + else + {R.initialize(CAMType::typeDouble,R1);} +// +// dgemm performs the operation R := alpha*op(S)*op(T) + beta*R; +// op(matrix) is either the matrix or its transpose. +// the characters transX below specify that S and T are 'n'ot +// to be transposed. +// +// R = m by n +// S = m by k +// T = k by n +// + char transa = 'n'; + char transb = 'n'; + + long m = R.Structure[1].getIndexCount(); + long n = R.Structure[2].getIndexCount(); + long k = (*S).Structure[2].getIndexCount(); + + double* s = (double*)((*S).getDataPointer()); + double* t = (double*)((*T).getDataPointer()); + double* r = (double*)( R.getDataPointer()); + + long lds = (*S).Structure[1].getIndexCount(); + long ldt = (*T).Structure[1].getIndexCount(); + long ldr = R.Structure[1].getIndexCount(); + + double alpha = 1.0; + double beta = 0.0; + + short f1 = 1; + short f2 = 1; + + dgemm_(&transa, &transb, &m, &n, &k, &alpha, s, &lds, t, &ldt, + &beta, r, &ldr,f1,f2); +// +// clean up +// + if(STempFlag == 1) delete S; + if(TTempFlag == 1) delete T; + + R.setTemporaryFlag(); + return R; +} +// +//***************************************************************** +// op = Operators +//***************************************************************** +// + +void CAMvectorBase::operator+=(const CAMvectorBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAplusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +// +//***************************************************************** +// op = Operators +//***************************************************************** +// + +void CAMvectorBase::operator+=(const CAMmatrixBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAplusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMvectorBase::operator-=(const CAMvectorBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAminusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} +void CAMvectorBase::operator-=(const CAMmatrixBase& A) +{ + if(Structure.isStrictConformingTo(A.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,A.Structure);} +// +// NEED CONVERSION CHECK +// + + CAMbinaryEngine::doubleAminusEqualB(Structure, *DataP, A.Structure, *A.DataP); +} + +CAMvectorBase CAMvectorBase::transpose() const +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(*this); +// +// Only need to change indices, since the copy constructor +// moves the data. +// + S.Structure.indexBegin[0] = Structure.indexBegin[1]; + S.Structure.indexBegin[1] = Structure.indexBegin[0]; + S.Structure.indexBeginBase[0] = Structure.indexBeginBase[1]; + S.Structure.indexBeginBase[1] = Structure.indexBeginBase[0]; + S.Structure.indexEnd[0] = Structure.indexEnd[1]; + S.Structure.indexEnd[1] = Structure.indexEnd[0]; + S.Structure.indexEndBase[0] = Structure.indexEndBase[1]; + S.Structure.indexEndBase[1] = Structure.indexEndBase[0]; + S.Structure.indexStride[0] = Structure.indexStride[1]; + S.Structure.indexStride[1] = Structure.indexStride[0]; + + S.setTemporaryFlag(); + return S; +} + + + +long CAMvectorBase::getIndexBase() const +{ + long dimensionReference = 1; + + if((Structure.indexEndBase[0] - Structure.indexBeginBase[0]) == 0) + dimensionReference = 2; + + return Structure.indexBegin[dimensionReference-1]; +} + +long CAMvectorBase::getIndexBound() const +{ + long dimensionReference = 1; + + if((Structure.indexEndBase[0] - Structure.indexBeginBase[0]) == 0) + dimensionReference = 2; + + return Structure.indexEnd[dimensionReference-1]; +} + + +long CAMvectorBase::getIndexStride() const +{ + long dimensionReference = 1; + + if((Structure.indexEndBase[0] - Structure.indexBeginBase[0]) == 0) + dimensionReference = 2; + + return Structure.indexStride[dimensionReference-1]; +} + +long CAMvectorBase::getIndexCount() const +{ + long dimensionReference = 1; + + if((Structure.indexEndBase[0] - Structure.indexBeginBase[0]) == 0) + dimensionReference =2; + + return ((Structure.indexEnd[dimensionReference - 1] + - Structure.indexBegin[dimensionReference - 1]) + 1); +} + +void CAMvectorBase::setIndexStride(long i) +{ + long dimensionReferenceA = 1; + long dimensionReferenceB = 2; + + if((Structure.indexEndBase[0] - Structure.indexBeginBase[0]) == 0) + {dimensionReferenceA = 2; dimensionReferenceB = 1;} + + + Structure.indexStride[dimensionReferenceA - 1] = i; + Structure.indexStride[dimensionReferenceB - 1] = 1; + + +} + +void CAMvectorBase::setIndexBase(long i) +{ + + long dimensionReferenceA = 1; + long dimensionReferenceB = 2; + + if((Structure.indexEndBase[0] - Structure.indexBeginBase[0]) == 0) + {dimensionReferenceA = 2; dimensionReferenceB = 1;} + + + long k = dimensionReferenceA - 1; + + long offset = i - Structure.indexBegin[k]; + Structure.indexBegin[k] = Structure.indexBegin[k] + offset; + Structure.indexEnd[k] = Structure.indexEnd[k] + offset; + Structure.indexBeginBase[k] = Structure.indexBeginBase[k] + offset; + Structure.indexEndBase[k] = Structure.indexEndBase[k] + offset; + + Structure.indexBegin[dimensionReferenceB - 1] = Structure.indexBegin[k]; + Structure.indexEnd[dimensionReferenceB - 1] = Structure.indexBegin[k]; + Structure.indexBeginBase[dimensionReferenceB - 1] = Structure.indexBegin[k]; + Structure.indexEndBase[dimensionReferenceB - 1] = Structure.indexBegin[k] ; + + +} + +CAMvectorBase CAMvectorBase::operator~() const +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(*this); +// +// Only need to change indices, since the copy constructor +// moves the data. +// + S.Structure.indexBegin[0] = Structure.indexBegin[1]; + S.Structure.indexBegin[1] = Structure.indexBegin[0]; + S.Structure.indexBeginBase[0] = Structure.indexBeginBase[1]; + S.Structure.indexBeginBase[1] = Structure.indexBeginBase[0]; + S.Structure.indexEnd[0] = Structure.indexEnd[1]; + S.Structure.indexEnd[1] = Structure.indexEnd[0]; + S.Structure.indexEndBase[0] = Structure.indexEndBase[1]; + S.Structure.indexEndBase[1] = Structure.indexEndBase[0]; + S.Structure.indexStride[0] = Structure.indexStride[1]; + S.Structure.indexStride[1] = Structure.indexStride[0]; + + S.setTemporaryFlag(); + return S; +} +// +//***************************************************************** +// Operations with Scalers +//***************************************************************** +// +CAMvectorBase CAMvectorBase::operator +(const double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,AStructure);} + + CAMvectorBase S(*this); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} +CAMvectorBase operator +(const double value, const CAMvectorBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase BStructure(_(1,1)); + if(A.Structure.isStrictConformingTo(BStructure) != 1) + {CAMvectorBase::nonConformingMessage(A.Structure,BStructure);} + + CAMvectorBase S(A); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +CAMvectorBase CAMvectorBase::operator -(const double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,AStructure);} + + CAMvectorBase S(*this); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +CAMvectorBase operator -(const double value, const CAMvectorBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase BStructure(_(1,1)); + if(A.Structure.isStrictConformingTo(BStructure) != 1) + {CAMvectorBase::nonConformingMessage(A.Structure,BStructure);} + + CAMvectorBase S(A); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value); + + S.setTemporaryFlag(); + return S; +} + +void CAMvectorBase::operator +=(const double value) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,AStructure);} + + CAMbinaryEngine::doubleAplusEqualAlpha(Structure, *(DataP), value); +} + +void CAMvectorBase::operator -=(const double value) +{ +// +// NEED CONVERSION CHECK +// + CAMstructureBase AStructure(_(1,1)); + if(Structure.isStrictConformingTo(AStructure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,AStructure);} + + CAMbinaryEngine::doubleAminusEqualAlpha(Structure, *(DataP), value); +} + +CAMvectorBase CAMvectorBase::operator*(double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(*this); + CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMvectorBase operator *(double value, const CAMvectorBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(A); + CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMvectorBase CAMvectorBase::operator /(double value) const +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(*this); + CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMvectorBase operator /(double value, const CAMvectorBase& A) +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(A); + CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +void CAMvectorBase::operator *=(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMbinaryEngine::doubleAtimesEqualAlpha(Structure, *DataP, value); +} + +void CAMvectorBase::operator /=(double value) +{ + CAMbinaryEngine::doubleAdivideEqualAlpha(Structure, *DataP, value); +} + + + +void CAMvectorBase::setToValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value); +} + +CAMvectorBase CAMvectorBase::plusValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(*this); + CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +CAMvectorBase CAMvectorBase::minusValue(double value) +{ +// +// NEED CONVERSION CHECK +// + CAMvectorBase S(*this); + CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *S.DataP, value); + S.setTemporaryFlag(); + return S; +} + +// +//***************************************************************** +// Temporary and Reference Utilities +//***************************************************************** +// +void CAMvectorBase::exchangeContentsWith(CAMvectorBase& B) +{ +// +// This routine exchanges the contents of *this with B. +// The routine is typically used with *this input as +// a null object and B a temporary object (i.e. the result +// of an operator or function which returns B with the +// temporary flag set). In such a case, the contents of +// B are captured by *this --- resulting in a transfer of the +// results without invoking a data copy. +// +// + CAMstructureBase S_temp(Structure); + CAMdataHandler* DataP_temp = DataP; + int typeValue_temp = typeValue; + int referenceFlag_temp = referenceFlag; + long vectorBaseReferenceCount_temp = vectorBaseReferenceCount; + + Structure.initialize(B.Structure); + DataP = B.DataP; + typeValue = B.typeValue; + referenceFlag = B.referenceFlag; + vectorBaseReferenceCount = B.vectorBaseReferenceCount; +// + B.Structure.initialize(S_temp); + B.DataP = DataP_temp; + B.typeValue = typeValue_temp; + B.referenceFlag = referenceFlag_temp; + B.vectorBaseReferenceCount = vectorBaseReferenceCount_temp; +} + +void CAMvectorBase::initializeReferenceDuplicate(const CAMvectorBase& B) +{ +// +// This routine initializes *this with the contents of B and +// and sets the *this reference flag. This results in a +// class instance whose data is that associated with B. +// +// Typically this routine is used in a container class which +// contains arrays --- and one wants to have sub-array access +// for the contained class which is based upon the sub-array +// access of the array class. +// + if(DataP != 0) + { + DataP->decrementReferenceCount(); + if(DataP->getReferenceCount() == 0) delete DataP; + } + + Structure.initialize(B.Structure); + DataP = B.DataP; + DataP->incrementReferenceCount(); //One Reference for local copy + DataP->incrementReferenceCount(); //One Reference for compiler copy + typeValue = B.typeValue; + referenceFlag = 1; + vectorBaseReferenceCount = 0; +} + +// +//***************************************************************** +// CONVERSIONS +//***************************************************************** +// +CAMmatrixBase CAMvectorBase::asMatrix() const +{ + CAMmatrixBase S; + if(DataP == 0) return S; + + CAMrange R1; CAMrange R2; + + if(Structure[1].getIndexCount() != 1) + { + R1.initialize(Structure[1].getIndexBase(), Structure[1].getIndexBound()); + R2.initialize(Structure[2].getIndexBase(), Structure[2].getIndexBound()); + } + else + { + R1.initialize(Structure[2].getIndexBase(), Structure[2].getIndexBound()); + R2.initialize(Structure[1].getIndexBase(), Structure[1].getIndexBound()); + } +// +// + S.initialize(CAMType::typeDouble, R1,R2); + CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP); +// +// + S.setTemporaryFlag(); + return S; +} +CAMarrayBase CAMvectorBase::asArray() const +{ + CAMarrayBase S; + if(DataP == 0) return S; + + CAMrange R1; + + if(Structure[1].getIndexCount() != 1) + { + R1.initialize(Structure[1].getIndexBase(), Structure[1].getIndexBound()); + } + else + { + R1.initialize(Structure[2].getIndexBase(), Structure[2].getIndexBound()); + } +// + S.initialize(CAMType::typeDouble, R1); + CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP); +// +// + S.setTemporaryFlag(); + return S; +} + + + +void* CAMvectorBase::getDataPointer(long i1, long i2) const +{ + const long* beginPtr = Structure.indexBeginBase.getDataPointer(); + const long* endPtr = Structure.indexEndBase.getDataPointer(); +// +// NEED CONVERSION CHECK +// + double* dataPtr = (double*)(DataP->dataPointer); + + long offset; + offset = (i1 - *(beginPtr)) + + ((*(endPtr) - *(beginPtr)) + 1)*(i2 - *(beginPtr + 1)); + + + return (void*)(dataPtr + offset); +} +// +//******************************************************************************** +// Reference Counting Functions +//******************************************************************************** +// + +void CAMvectorBase::incrementReferenceCount() +{ + if(vectorBaseReferenceCount == 0) CAMvectorBase::referenceCountError(); + vectorBaseReferenceCount++; +} + +void CAMvectorBase::referenceCountError() +{ +cerr << " Cannot Use Reference Counting on Objects New\'d by the Compiler " << endl; +CAMmvaExit(); +} +// +//***************************************************************** +// MEMBER_FUNCTIONS +//***************************************************************** +// + + +void CAMvectorBase::indexCheck(const CAMstructureBase &S, long i1, long i2) +{ + if(S.dataDimension != 2) + { + cerr << " Error : Incorrect Vector Array Index Dimension " << endl; + cerr << " Object Dimension = " << S.dataDimension + << "--- Dimension Used = "<< 2 << endl; + CAMmvaExit(); + } + const long* indexBeginP = S.indexBegin.getDataPointer(); + const long* indexEndP = S.indexEnd.getDataPointer(); + if((i1 < *indexBeginP)||(i1 > *indexEndP)) + { + CAMvectorBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1); + } + if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1))) + { + CAMvectorBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2); + } +} + + + + + +void CAMvectorBase::indexErrorMessage(long indexDimension, long base, long bound, long index) +{ + cerr << " Error : Index " << indexDimension << " Out of Range " << endl; + + cerr << " Current Index Range :(" << base << ", " << bound << ")" << endl; + cerr << " Index Used : " << index << endl; + CAMmvaExit(); +} +void CAMvectorBase::nonConformingMessage(const CAMstructureBase& A, const CAMstructureBase& B) +{ + long i; + cerr << endl; + cerr << "Error : Object Dimensions not Compatable with Operation " << endl << endl; + cerr << "Left Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + cerr << "Right Operand Dimensions : "; + cerr << B[1].getIndexCount(); + for(i = 2; i <= B.dataDimension; i++) + cerr << " x " << B[i].getIndexCount(); + cerr << endl << endl; + CAMmvaExit(); +} +void CAMvectorBase::doubleConversionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << "Dimensions not Compatable with Conversion to Double " << endl << endl; + cerr << "Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} + +void CAMvectorBase::objectConversionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << " Dimensions not Compatable with Conversion Operator " << endl << endl; + cerr << "Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +void CAMvectorBase::nullOperandError() +{ + cerr << endl; + cerr << " Error : Null Object Used As Operand " << endl; + CAMmvaExit(); +} +void CAMvectorBase::nullOperandError(char* Operation) +{ + cerr << endl; + cerr << " Error : Null Object Used As Operand With "<< Operation << endl; + CAMmvaExit(); +} +void CAMvectorBase::inputSizeError() +{ + cerr << endl; + cerr << " Input error : Insufficient # of data elements in input stream " << endl; + CAMmvaExit(); +} +// +//***************************************************************** +// CPP File End +//***************************************************************** +// + + + + + + + + + + + diff --git a/src/matrix/vecbse.h b/src/matrix/vecbse.h new file mode 100755 index 0000000..8a4f8ce --- /dev/null +++ b/src/matrix/vecbse.h @@ -0,0 +1,203 @@ +// +//****************************************************************************** +// VECBSE.H +//****************************************************************************** +// + +#include +#include +#include "strctbse.h" +#include "datahndl.h" +#include "access.h" +#include "mvaexit.h" +#include "camtype.h" +#include "typehndl.h" + +// +// +// +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Tue Apr 16 11:30:42 1996 +// +//******************************************************************************** +// +#ifndef __NO_COMPLEX__ +#define __NO_COMPLEX__ +#endif +// +// +#include "mvaimpexp.h" // C +// +// +#ifndef _CAMMATRIXBASE_ +class CAMmatrixBase; +#endif +#ifndef _CAMARRAYBASE_ +class CAMarrayBase; +#endif +// +// +// + +#ifndef _CAMVECTORBASE_ +#define _CAMVECTORBASE_ + + +class __IMPEXP__ CAMvectorBase +{ + +public : + + CAMstructureBase Structure; + CAMdataHandler* DataP; + int typeValue; + int referenceFlag; + long vectorBaseReferenceCount; + +public : + + friend class CAMmatrixBase; + +// +// Constructors +// + CAMvectorBase(); + CAMvectorBase( const CAMvectorBase& A); + CAMvectorBase(int d_type); + CAMvectorBase(int d_type, const CAMrange& R1); +// +// Destructor +// + ~CAMvectorBase(); +// +// Assignment +// + void operator = (double value); + void operator = (const CAMvectorBase& A); + void operator = (const CAMmatrixBase& A); +// +// Output +// + __IMPEXP__ friend ostream& operator <<(ostream& out_stream, const CAMvectorBase& A); +// +// Input +// + __IMPEXP__ friend istream& operator >>(istream& in_stream, CAMvectorBase& A); +// +// Initialization Functions +// + void initialize(); + void initialize(const CAMvectorBase& A); + void initialize(int d_type); + void initialize(int d_type, const CAMrange& R1); +// +// Unary and Binary Operations +// + CAMvectorBase operator-() const; + CAMvectorBase operator+(const CAMvectorBase& A) const; + CAMmatrixBase operator+(const CAMmatrixBase& A) const; + CAMvectorBase operator-(const CAMvectorBase& A) const; + CAMmatrixBase operator-(const CAMmatrixBase& A) const; + CAMmatrixBase operator*(const CAMvectorBase& A) const; + CAMvectorBase operator*(const CAMmatrixBase& A) const; + void operator+=(const CAMvectorBase& A); + void operator+=(const CAMmatrixBase& A); + void operator-=(const CAMvectorBase& A); + void operator-=(const CAMmatrixBase& A); + CAMvectorBase operator~() const; + CAMvectorBase transpose() const; + + long CAMvectorBase::getIndexBase() const; + long CAMvectorBase::getIndexBound() const; + long CAMvectorBase::getIndexStride() const; + long CAMvectorBase::getIndexCount() const; + void CAMvectorBase::setIndexBase(long i); + void CAMvectorBase::setIndexStride(long i); + +// +// Scaler Operations +// + CAMvectorBase operator +(const double value) const; + __IMPEXP__ friend CAMvectorBase operator +(const double value, const CAMvectorBase& A); + CAMvectorBase operator -(const double value) const; + __IMPEXP__ friend CAMvectorBase operator -(const double value, const CAMvectorBase& A); + void operator +=(const double value); + void operator -=(const double value); + CAMvectorBase operator *(double value) const; + __IMPEXP__ friend CAMvectorBase operator *(double value, const CAMvectorBase& A); + CAMvectorBase operator /(double value) const; + __IMPEXP__ friend CAMvectorBase operator /(double value, const CAMvectorBase& A); + void operator *=(double value); + void operator /=(double value); +// +// Additional Scalar Functions +// + void setToValue(double value); + CAMvectorBase plusValue(double value); + CAMvectorBase minusValue(double value); +// +// Helper Functions +// + void setTemporaryFlag(){DataP->setTemporaryFlag();}; + void initializeReturnArgument(const CAMstructureBase& S, int dataT); + void initializeReturnArgument(const CAMvectorBase& A); + void initializeMinDuplicate(const CAMvectorBase& A); + void* getDataPointer() const {return DataP->getDataPointer();}; + void* getDataPointer(long i1, long i2) const; + CAMmatrixBase asMatrix() const; + CAMarrayBase asArray() const; +// + long getDimension() const {return 1;}; +// +// Reference Counting +// + void incrementReferenceCount(); + void decrementReferenceCount(){vectorBaseReferenceCount--;}; + int getReferenceCount() const {return vectorBaseReferenceCount;}; + void setReferenceCount(int refValue){vectorBaseReferenceCount = refValue;}; + static void referenceCountError(); +// +// Error Handling Routines +// + static void indexCheck(const CAMstructureBase &S, long i1, long i2); + static void indexErrorMessage(long indexDimension, long base, long bound, long index); + static void nonConformingMessage(const CAMstructureBase &A,const CAMstructureBase &B); + static void doubleConversionError(const CAMstructureBase& A); + static void objectConversionError(const CAMstructureBase& A); + static void nullOperandError(); + static void nullOperandError(char* Operation); + static void inputSizeError(); +// +// Utility Functions +// + double max() const; + double min() const; + double maxAbs() const; + double minAbs() const; + double infNorm() const; + double pNorm(int p) const; + double pNorm(long p) const; + double pNorm(float p) const; + double pNorm(double p) const; + + double dot(const CAMvectorBase& V) const; + +// +// temporary and reference utility functions +// + void exchangeContentsWith(CAMvectorBase& B); + void initializeReferenceDuplicate(const CAMvectorBase& B); + +}; + +#endif +// +//******************************************************************************** +// Header File End +//******************************************************************************** +// + diff --git a/src/matrix/vecgph.cpp b/src/matrix/vecgph.cpp new file mode 100755 index 0000000..b2b8a87 --- /dev/null +++ b/src/matrix/vecgph.cpp @@ -0,0 +1,178 @@ +#include "vecbse.h" +// +//****************************************************************************** +// VECGPH.CPP +//****************************************************************************** +// +// BINDINGS TO THE UC GRAHPICS CLASSES +// +//******************************************************************************** +// +// Chris Anderson (C) UCLA +// +// Tue Sep 26 14:40:00 1995 +// +//******************************************************************************** +// + +// +// Graphics Bindings +// +void CAMvectorBase::plot() const +{ +// +// Need Conversion Check +// + long M; + + CAMvectorBase A; + double* AdataPtr; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataPtr = (double*)A.getDataPointer(); + M = A.getIndexCount(); + } + else + { + AdataPtr = (double*)getDataPointer(); + M = getIndexCount(); + } + + CAMgraphics::plot(AdataPtr,M); +} + +void CAMvectorBase::plot(int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + if(p_arg < 32) + { CAMgraphics::setPlotStyle(p_arg);} + else + { CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(CAMgraphics::POINTS); + } + + this->plot(); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} +void CAMvectorBase::plot(int p_style, int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(p_style); + + this->plot(); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} + + +void CAMvectorBase::plot(const CAMvectorBase& Ordinates) const +{ +// +// Need Conversion Check +// + long M; + + CAMvectorBase A; + double* AdataPtr; + + CAMvectorBase O; + double* OdataPtr; + long Ocount; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataPtr = (double*)A.getDataPointer(); + M = A.getIndexCount(); + } + else + { + AdataPtr = (double*)getDataPointer(); + M = getIndexCount(); + } + + if(Ordinates.Structure.isSubset() == 1) + { + O.initializeMinDuplicate(Ordinates); + OdataPtr = (double*)O.getDataPointer(); + Ocount = O.getIndexCount(); + } + else + { + OdataPtr = (double*)Ordinates.getDataPointer(); + Ocount = Ordinates.getIndexCount(); + } + + if(M != Ocount) + {CAMvectorBase::ordinateError(Ordinates.Structure);} + + CAMgraphics::plot(OdataPtr,AdataPtr,M); +} +void CAMvectorBase::plot(const CAMvectorBase& Ordinates, int p_arg) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + if(p_arg < 32) + { CAMgraphics::setPlotStyle(p_arg);} + else + { CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(CAMgraphics::POINTS); + } + + this->plot(Ordinates); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} + +void CAMvectorBase::plot(const CAMvectorBase& Ordinates, int p_arg, int p_style) const +{ + char point_type_save = CAMgraphics::getPointType(); + int plot_style_save = CAMgraphics::getPlotStyle(); + CAMgraphics::setPointType(char(p_arg)); + CAMgraphics::setPlotStyle(p_style); + + this->plot(Ordinates); + + CAMgraphics::setPointType(point_type_save); + CAMgraphics::setPlotStyle(plot_style_save); +} + +void CAMvectorBase::ordinateError(const CAMstructureBase & A) +{ + long i; + cerr << endl; + cerr << " Ordinates in Plot Command Incorrectly Specified " << endl << endl; + cerr << " Error in Number of Ordinates or Ordinate Array Dimension " << endl; + cerr << " Ordinates Size : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +void CAMvectorBase::plotDimensionError(const CAMstructureBase& A) +{ + long i; + cerr << endl; + cerr << "Error : Object Dimensions not Compatable with Plot Operation " << endl << endl; + cerr << " Operand Dimensions : "; + cerr << A[1].getIndexCount(); + for(i = 2; i <= A.dataDimension; i++) + cerr << " x " << A[i].getIndexCount() ; + cerr << endl << endl; + CAMmvaExit(); +} +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// diff --git a/src/matrix/vecutl.cpp b/src/matrix/vecutl.cpp new file mode 100755 index 0000000..64124ad --- /dev/null +++ b/src/matrix/vecutl.cpp @@ -0,0 +1,227 @@ +#include "vecbse.h" +#include "bnengine.h" +// +//******************************************************************************** +// UTILITY MEMBER_FUNCTIONS +//******************************************************************************** +// +// +// Routines return double. When adding multiple data types, I'll +// need to promote the utilities to the derived classes so that +// they can return the appropriate type. +// +double CAMvectorBase::max() const +{ +// +// Need Conversion Check +// + CAMvectorBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxValue(AdataP, n, value); + return value; +} + +double CAMvectorBase::min() const +{ +// +// Need Conversion Check +// + CAMvectorBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMinValue(AdataP, n, value); + return value; +} + +double CAMvectorBase::maxAbs() const +{ +// +// Need Conversion Check +// + CAMvectorBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxAbsValue(AdataP, n, value); + return value; +} + +double CAMvectorBase::minAbs() const +{ +// +// Need Conversion Check +// + CAMvectorBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMinAbsValue(AdataP, n, value); + return value; +} + + +double CAMvectorBase::infNorm() const +{ +// +// Need Conversion Check +// + CAMvectorBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doubleMaxAbsValue(AdataP, n, value); + return value; +} + +double CAMvectorBase::pNorm(double p) const +{ +// +// Need Conversion Check +// + CAMvectorBase A; + double* AdataP; + long n; + double value; + + if(A.Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataP = (double*)A.getDataPointer(); + n = A.Structure.getFullDataCount(); + } + else + { + AdataP = (double*)getDataPointer(); + n = Structure.getFullDataCount(); + } + + CAMbinaryEngine::doublepNorm(AdataP, n, p, value); + return value; +} + +double CAMvectorBase::pNorm(int p) const {return pNorm(double(p));} +double CAMvectorBase::pNorm(long p) const {return pNorm(double(p));} +double CAMvectorBase::pNorm(float p) const {return pNorm(double(p));} +double CAMvectorBase::dot(const CAMvectorBase& V) const +{ +// +// Need Conversion Check +// + + if(Structure.isConformingTo(V.Structure) != 1) + {CAMvectorBase::nonConformingMessage(Structure,V.Structure);} + + long M; + + CAMvectorBase A; + double* AdataPtr; + + CAMvectorBase Vb; + double* VdataPtr; + long Vcount; + + if(Structure.isSubset() == 1) + { + A.initializeMinDuplicate(*this); + AdataPtr = (double*)A.getDataPointer(); + M = A.getIndexCount(); + } + else + { + AdataPtr = (double*)getDataPointer(); + M = getIndexCount(); + } + + if(V.Structure.isSubset() == 1) + { + Vb.initializeMinDuplicate(V); + VdataPtr = (double*)Vb.getDataPointer(); + } + else + { + VdataPtr = (double*)V.getDataPointer(); + } + + double sum = 0.0; + long i; + for(i = 0; i < M; i++) + { + sum += (*(VdataPtr + i))*(*(AdataPtr + i)); + } + return sum; +} +// +//******************************************************************************** +// CPP File End +//******************************************************************************** +// + + diff --git a/src/orbit/CVS/Entries b/src/orbit/CVS/Entries new file mode 100644 index 0000000..b954cf6 --- /dev/null +++ b/src/orbit/CVS/Entries @@ -0,0 +1,10 @@ +/Jamfile/1.4/Mon Dec 8 14:48:27 2003// +/Makefile/1.8/Sat Oct 18 21:37:28 2003// +/Orbit.cpp/1.8/Tue Jun 10 14:52:04 2003// +/Orbit.h/1.10/Sat Oct 18 21:37:28 2003// +/OrbitState.cpp/1.9/Thu Jun 12 23:08:20 2003// +/OrbitState.h/1.10/Sat Oct 18 21:37:28 2003// +/orbit.pro/1.3/Sat Oct 18 21:37:28 2003// +D/orbitframes//// +D/orbitmodels//// +D/orbitstaterep//// diff --git a/src/orbit/CVS/Repository b/src/orbit/CVS/Repository new file mode 100644 index 0000000..9bb084e --- /dev/null +++ b/src/orbit/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/orbit diff --git a/src/orbit/CVS/Root b/src/orbit/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/orbit/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/orbit/Jamfile b/src/orbit/Jamfile new file mode 100644 index 0000000..7dd2678 --- /dev/null +++ b/src/orbit/Jamfile @@ -0,0 +1,35 @@ +########################################### +# Orbit Jamfile +# +# $Author: simpliciter $ +# $Revision: 1.4 $ +# $Date: 2003/12/08 14:48:27 $ +########################################### + +SubDir OPENSESSAME_ROOT src orbit ; + +### NOTE! Lines that are currently commented out include the ECEF frame which currently does not compile. Someone should fix this compile issue and then return to the complete lines of code! + +Objects Orbit.cpp OrbitState.cpp orbitframes$(SLASH)OrbitFrame.cpp orbitstaterep$(SLASH)Keplerian.cpp orbitstaterep$(SLASH)OrbitStateRepresentation.cpp orbitstaterep$(SLASH)PositionVelocity.cpp ; +ObjectHdrs Orbit.cpp OrbitState.cpp orbitframes$(SLASH)OrbitFrame.cpp orbitstaterep$(SLASH)Keplerian.cpp orbitstaterep$(SLASH)OrbitStateRepresentation.cpp orbitstaterep$(SLASH)PositionVelocity.cpp : $(OPENSESSAME_HDRS) ; +#Objects Orbit.cpp OrbitState.cpp orbitframes$(SLASH)OrbitFrame.cpp orbitframes$(SLASH)OrbitFrameECEF.cpp orbitstaterep$(SLASH)Keplerian.cpp orbitstaterep$(SLASH)OrbitStateRepresentation.cpp orbitstaterep$(SLASH)PositionVelocity.cpp ; +#ObjectHdrs Orbit.cpp OrbitState.cpp orbitframes$(SLASH)OrbitFrame.cpp orbitframes$(SLASH)OrbitFrameECEF.cpp orbitstaterep$(SLASH)Keplerian.cpp orbitstaterep$(SLASH)OrbitStateRepresentation.cpp orbitstaterep$(SLASH)PositionVelocity.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)orbit : Orbit$(SUFOBJ) OrbitState$(SUFOBJ) orbitframes$(SLASH)OrbitFrame$(SUFOBJ) orbitstaterep$(SLASH)Keplerian$(SUFOBJ) orbitstaterep$(SLASH)OrbitStateRepresentation$(SUFOBJ) orbitstaterep$(SLASH)PositionVelocity$(SUFOBJ) ; +#LibraryFromObjects $(PFXLIB)orbit : Orbit$(SUFOBJ) OrbitState$(SUFOBJ) orbitframes$(SLASH)OrbitFrame$(SUFOBJ) orbitframes$(SLASH)OrbitFrameECEF$(SUFOBJ) orbitstaterep$(SLASH)Keplerian$(SUFOBJ) orbitstaterep$(SLASH)OrbitStateRepresentation$(SUFOBJ) orbitstaterep$(SLASH)PositionVelocity$(SUFOBJ) ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)orbit$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : Orbit.h OrbitState.h orbitframes$(SLASH)OrbitFrame.h orbitframes$(SLASH)OrbitFrameEQW.h orbitframes$(SLASH)OrbitFrameIJK.h orbitframes$(SLASH)OrbitFrameNTW.h orbitframes$(SLASH)OrbitFramePQW.h orbitframes$(SLASH)OrbitFrameRSW.h orbitframes$(SLASH)OrbitFrameSEZ.h orbitmodels$(SLASH)TwoBodyDynamics.h orbitstaterep$(SLASH)Keplerian.h orbitstaterep$(SLASH)OrbitStateRepresentation.h orbitstaterep$(SLASH)PositionVelocity.h ; +##InstallFile $(OPENSESSAME_INCLUDEDIR) : Orbit.h OrbitState.h orbitframes$(SLASH)OrbitFrame.h orbitframes$(SLASH)OrbitFrameECEF.h orbitframes$(SLASH)OrbitFrameEQW.h orbitframes$(SLASH)OrbitFrameIJK.h orbitframes$(SLASH)OrbitFrameNTW.h orbitframes$(SLASH)OrbitFramePQW.h orbitframes$(SLASH)OrbitFrameRSW.h orbitframes$(SLASH)OrbitFrameSEZ.h orbitmodels$(SLASH)TwoBodyDynamics.h orbitstaterep$(SLASH)Keplerian.h orbitstaterep$(SLASH)OrbitStateRepresentation.h orbitstaterep$(SLASH)PositionVelocity.h ; + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.4 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# ******************************************************************************/ + + + diff --git a/src/orbit/Makefile b/src/orbit/Makefile new file mode 100644 index 0000000..2b47b36 --- /dev/null +++ b/src/orbit/Makefile @@ -0,0 +1,269 @@ +############################################################################# +# Makefile for building: ../../lib/libosessame_orbit.a +# Generated by qmake (1.02a) on: Sat Oct 18 17:32:56 2003 +# Project: orbit.pro +# Template: lib +# Command: $(QMAKE) orbit.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +LEX = flex +YACC = yacc +CFLAGS = -pipe -Wall -W -g +CXXFLAGS = -pipe -Wall -W -g +LEXFLAGS = +YACCFLAGS= -d +INCPATH = -I../matrix -I../rotation -I../attitude -I../orbit -I../datahandling -I../dynamics -I../environment -I.. -I$(QTDIR)/mkspecs/default +AR = ar cqs +RANLIB = +MOC = $(QTDIR)/bin/moc +UIC = $(QTDIR)/bin/uic +QMAKE = qmake +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE= $(COPY) -p +COPY_DIR = $(COPY) -pR +DEL_FILE = +DEL_DIR = +MOVE = mv + +####### Output directory + +OBJECTS_DIR = ../../objects/ + +####### Files + +HEADERS = Orbit.h \ + OrbitState.h \ + orbitstaterep/OrbitStateRepresentation.h \ + orbitstaterep/PositionVelocity.h \ + orbitstaterep/Keplerian.h \ + orbitframes/OrbitFrame.h +SOURCES = Orbit.cpp \ + OrbitState.cpp \ + orbitstaterep/OrbitStateRepresentation.cpp \ + orbitstaterep/PositionVelocity.cpp \ + orbitstaterep/Keplerian.cpp \ + orbitframes/OrbitFrame.cpp +OBJECTS = ../../objects/Orbit.o \ + ../../objects/OrbitState.o \ + ../../objects/OrbitStateRepresentation.o \ + ../../objects/PositionVelocity.o \ + ../../objects/Keplerian.o \ + ../../objects/OrbitFrame.o +FORMS = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = +DIST = +QMAKE_TARGET = osessame_orbit +DESTDIR = ../../lib/ +TARGET = ../../lib/libosessame_orbit.a + +first: all +####### Implicit rules + +.SUFFIXES: .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: Makefile $(TARGET) + +staticlib: $(TARGET) + +$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) + test -d ../../lib/ || mkdir -p ../../lib/ + -rm -f $(TARGET) + $(AR) $(TARGET) $(OBJECTS) $(OBJMOC) + + +mocables: $(SRCMOC) + +$(MOC): + ( cd $(QTDIR)/src/moc ; $(MAKE) ) + +Makefile: orbit.pro $(QTDIR)/mkspecs/default/qmake.conf + $(QMAKE) orbit.pro +qmake: + @$(QMAKE) orbit.pro + +dist: + @mkdir -p ../../objects/osessame_orbit && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) ../../objects/osessame_orbit/ && ( cd `dirname ../../objects/osessame_orbit` && $(TAR) osessame_orbit.tar osessame_orbit && $(GZIP) osessame_orbit.tar ) && mv `dirname ../../objects/osessame_orbit`/osessame_orbit.tar.gz . && rm -rf ../../objects/osessame_orbit + +uiclean: + +clean: + -rm -f $(OBJECTS) + -rm -f *~ core *.core + + +####### Sub-libraries + +distclean: clean + -rm -f ../../lib/$(TARGET) $(TARGET) + + +FORCE: + +####### Compile + +../../objects/Orbit.o: Orbit.cpp Orbit.h \ + ../environment/Environment.h \ + ../dynamics/Propagator.h \ + OrbitState.h \ + ../datahandling/OrbitHistory.h \ + ../rotation/Rotation.h \ + ../matrix/Matrix.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/Orbit.h \ + ../attitude/Attitude.h \ + ../datahandling/AttitudeHistory.h \ + ../attitude/AttitudeState.h \ + ../datahandling/History.h \ + ../orbit/OrbitState.h \ + ../orbit/orbitstaterep/PositionVelocity.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/Orbit.o Orbit.cpp + +../../objects/OrbitState.o: OrbitState.cpp OrbitState.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h \ + ../rotation/Rotation.h \ + ../matrix/Matrix.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/OrbitState.o OrbitState.cpp + +../../objects/OrbitStateRepresentation.o: orbitstaterep/OrbitStateRepresentation.cpp orbitstaterep/OrbitStateRepresentation.h \ + ../matrix/Matrix.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../rotation/Rotation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/OrbitStateRepresentation.o orbitstaterep/OrbitStateRepresentation.cpp + +../../objects/PositionVelocity.o: orbitstaterep/PositionVelocity.cpp orbitstaterep/PositionVelocity.h \ + ../matrix/Matrix.h \ + ../orbit/orbitstaterep/OrbitStateRepresentation.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../rotation/Rotation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/PositionVelocity.o orbitstaterep/PositionVelocity.cpp + +../../objects/Keplerian.o: orbitstaterep/Keplerian.cpp orbitstaterep/Keplerian.h \ + ../matrix/Matrix.h \ + orbitstaterep/OrbitStateRepresentation.h \ + ../matrix/cammva.h \ + ../matrix/dmatrix.h \ + ../matrix/dvector.h \ + ../matrix/darray.h \ + ../matrix/strctbse.h \ + ../matrix/datahndl.h \ + ../matrix/matbse.h \ + ../matrix/vecbse.h \ + ../matrix/range.h \ + ../matrix/camtype.h \ + ../matrix/under.h \ + ../matrix/mvaimpexp.h \ + ../matrix/mvalngbase.h \ + ../matrix/access.h \ + ../matrix/mvaexit.h \ + ../matrix/typehndl.h \ + ../matrix/arraybse.h \ + ../orbit/orbitframes/OrbitFrame.h \ + ../rotation/Rotation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/Keplerian.o orbitstaterep/Keplerian.cpp + +../../objects/OrbitFrame.o: orbitframes/OrbitFrame.cpp orbitframes/OrbitFrame.h \ + ../rotation/Rotation.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ../../objects/OrbitFrame.o orbitframes/OrbitFrame.cpp + +####### Install + +install: all + +uninstall: + diff --git a/src/orbit/Orbit.cpp b/src/orbit/Orbit.cpp new file mode 100644 index 0000000..d0d4705 --- /dev/null +++ b/src/orbit/Orbit.cpp @@ -0,0 +1,146 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Orbit.cpp +* \brief Implementation of the Orbit Interface Class. +* \author $Author: nilspace $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/06/10 14:52:04 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Orbit.h" +#include "Environment.h" +namespace O_SESSAME { + +Orbit::Orbit() : m_CurrentOrbitPosition(), m_pPropagator(NULL), m_Integrateable(false), m_Parameters(), m_pEnvironment(NULL), m_ControlForces() +{ +} + +Orbit::~Orbit() +{ +/*! \todo determine how to clean up the orbit pointers without leaving references hanging + if(m_pEnvironment) + delete m_pEnvironment; + if(m_pPropagator) + delete m_pPropagator; +*/ +} +void Orbit::SetStateObject(const OrbitState &_currentOrbitPosition) +{ + m_CurrentOrbitPosition = _currentOrbitPosition; +} + +OrbitState Orbit::GetStateObject() const +{ + return m_CurrentOrbitPosition; +} + +void Orbit::SetPropagator(Propagator *_pPropagator) +{ + m_pPropagator = _pPropagator; + m_pPropagator->SetOrbitObject(this); +} + +Propagator* Orbit::GetPropagator() +{ + return m_pPropagator; +} + +void Orbit::SetDynamicsEq(odeFunctor _orbitDynamicsEq) +{ + m_OrbitDynamicsEq = _orbitDynamicsEq; + m_Integrateable = true; +} +odeFunctor Orbit::GetDynamicsEq() +{ + return m_OrbitDynamicsEq; +} + +void Orbit::SetStateConversion(IntegratedOrbitStateConversionFunction _ConversionFunction) +{ + m_OrbitStateConversionFunction = _ConversionFunction; +} + +IntegratedOrbitStateConversionFunction Orbit::GetStateConversion() const +{ + return m_OrbitStateConversionFunction; +} + + +bool Orbit::IsIntegrateable() +{ + return m_Integrateable; +} + +void Orbit::SetParameters(const Matrix &_Parameters) +{ + m_Parameters.initialize(_Parameters); +} + +Matrix Orbit::GetParameters() const +{ + return m_Parameters; +} +void Orbit::SetEnvironment(Environment *_pEnvironment) +{ + m_pEnvironment = _pEnvironment; + m_EnvironmentForcesFunctor.Set(m_pEnvironment, &Environment::GetForces); +} + +Environment* Orbit::GetEnvironment() +{ + return m_pEnvironment; +} +void Orbit::SetControlForces(const Vector &_controlForces) +{ + m_ControlForces.initialize(_controlForces); +} + +Vector Orbit::GetControlForces() +{ + return m_ControlForces; +} + +ObjectFunctor Orbit::GetEnvironmentForcesFunctor() +{ + return m_EnvironmentForcesFunctor; +} + +OrbitHistory& Orbit::GetHistoryObject() +{ + return m_OrbitHistory; +} +} // end of namespace O_SESSAME +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Orbit.cpp,v $ +* Revision 1.8 2003/06/10 14:52:04 nilspace +* Changed GetHistory to GetHistoryObject +* +* Revision 1.7 2003/05/22 21:03:07 nilspace +* Updated comments. +* +* Revision 1.6 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.5 2003/04/28 20:13:17 nilspace +* GetHistory return by reference. +* +* Revision 1.4 2003/04/27 21:17:42 nilspace +* Finished moving function declarations out of the class interface. +* +* Revision 1.3 2003/04/27 21:14:01 nilspace +* Added to the namespace O_SESSAME. +* Moved function definitions outside of the class interface definition. +* +* Revision 1.2 2003/04/25 13:36:57 nilspace +* Updated to work with current History, Environment, & Propagator objects. +* +* Revision 1.1 2003/04/08 22:48:59 nilspace +* Initial Submission. +* +* +* +******************************************************************************/ diff --git a/src/orbit/Orbit.h b/src/orbit/Orbit.h new file mode 100644 index 0000000..401e532 --- /dev/null +++ b/src/orbit/Orbit.h @@ -0,0 +1,251 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Orbit.h +* \brief Implementation of the Orbit Class. +* \author $Author: rsharo $ +* \version $Revision: 1.10 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_H__ +#define __SSF_ORBIT_H__ + +#include "utils/Functor.h" +#include "Environment.h" +#include "Propagator.h" +#include "OrbitState.h" +#include "OrbitHistory.h" + + +namespace O_SESSAME { +class Propagator; // forward declaration + +/*! \brief Defined function pointer to integrated orbital state conversion function. + * \ingroup PropagatorToolkit + * + * Converts a vector of meshpoints (from integrated states) to the corresponding generalized OrbitState. + * @param _meshPoint vector of values of the meshpoint to be converted + * @param _convertedOrbitState Calculated Orbit state from the converted meshpoint that is returned to the caller. + */ +typedef void (*IntegratedOrbitStateConversionFunction)(const Matrix &_meshPoint, OrbitState &_convertedOrbitState); + + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup OrbitToolkit Orbit Toolkit +* +* Collection of orbit analysis and simulation tools. +* @{ +*/ + +/*! @defgroup OrbitEquationsOfMotion Orbit Equations of Motion +* @ingroup OrbitToolkit +* +*/ + +/*! \brief Complete representation of a spacecraft orbt. +* +* The Orbit class is a composition of all the information that is part of a spacecraft orbit. This includes +the dynamic equations, disturbance force functions, environmen objects, state history and control forces. +*/ + +/** \example testOrbitIntegration.cpp +* \example testPropagation.cpp +*/ +class Orbit +{ +public: + /*! Default Constructor */ + Orbit(); + /*! Default Deconstructor */ + virtual ~Orbit(); + +public: + /*! \brief Set the current orbit state object that represents the spacecraft's position in space. + * @param _currentOrbitPosition Current orbital state of the spacecraft. + */ + void SetStateObject(const OrbitState& _currentOrbitPosition); + + /*! \brief Return the current orbital state of the spacecraft. + * @return Current stored orbital state of the spacecraft. + */ + OrbitState GetStateObject() const; + +protected: + /*! \brief Current stored orbital state of the spacecraft. */ + OrbitState m_CurrentOrbitPosition; + + +// ***************************** +// ******** PROPAGATION ******** +// ***************************** +public: + /*! \brief Set the Dynamics Equation right-hand side file + * @param _orbitDynamicsEq pointer to the right-hand side dynamics equation + */ + void SetDynamicsEq(odeFunctor _orbitDynamicsEq); + + /*! \brief Return the pointer to the Dynamics Equation right-hand side + * @return pointer to the right-hand side dynamics equation + */ + odeFunctor GetDynamicsEq(); + + /*! \brief Set the Orbit state conversion function. + * @param _ConversionFunction pointer to the conversion function (takes a meshpoint and returns an object of OrbitState). + */ + void SetStateConversion(IntegratedOrbitStateConversionFunction _ConversionFunction); + + /*! \brief Get the Orbit state conversion function. + * @return pointer to the conversion function (takes a meshpoint and returns an object of OrbitState). + */ + IntegratedOrbitStateConversionFunction GetStateConversion() const; + + /*! \brief Sets the propagator used for integrating the orbit. + * @param _pPropagator Pointer to the propagator to be used. + */ + void SetPropagator(Propagator *_pPropagator); + + /*! \brief Returns the pointer to the propagator being used. + * @return pointer to the orbit's propagator. + */ + Propagator* GetPropagator(); + + /*! \brief Propagate the orbit through the vector of times. + */ + void Propagate(const Vector &_propTime); + + /*! \brief Returns whether the orbit is integrateable or not. + * Determined if there is a dynamics equation present. + * @return true if the orbit can be integrated, false if it can't. + */ + bool IsIntegrateable(); + +private: + /*! \brief Internal pointer to the current orbit propagator algorithm */ + Propagator *m_pPropagator; + + /*! Conversion function for converting from the integrated states to an Orbit State. */ + IntegratedOrbitStateConversionFunction m_OrbitStateConversionFunction; + + /*! \brief Right-hand side of the orbit dynamics equation: \f$\dot{x} = RHS(t, x)\f$ */ + odeFunctor m_OrbitDynamicsEq; + + /*! \brief Is the orbit integrateable? (true if it is, false if is not) */ + bool m_Integrateable; + +// ***************************** +// ********* Physical ********** +// ***************************** +public: + /*! \brief Set the physical parameters of the spacecraft orbit + * + * \todo determine what physical parameters are pertinent. + */ + void SetParameters(const Matrix &_Parameters); + + /*! \brief Return a matrix of the current stored spacecraft orbital parameters. + * + */ + Matrix GetParameters() const; + +private: + Matrix m_Parameters; + +// ***************************** +// ******** ENVIRONMENT ******** +// ***************************** +public: + /*! \brief Sets the environment used for integrating the orbit. + * @param _pEnvironment Instance of the environment to be used. + */ + void SetEnvironment(Environment *_pEnvironment); + + /*! \brief Returns the environment used for integrating the orbit. + * @return pointer to the instance of the environment being used. + */ + Environment* GetEnvironment(); + + + void SetControlForces(const Vector &_controlForces); + Vector GetControlForces(); + + /*! \brief Return a reference to the environmental forces function. + * @return the Functor that references the Environment force function of the orbit. Used as a + * callback function for evaluating the forces on the spacecraft orbit due to + * specified environmental disturbances. + */ + ObjectFunctor GetEnvironmentForcesFunctor(); +private: + /*! \brief Internal pointer to the orbit's environment object. */ + Environment *m_pEnvironment; + /*! \brief Internal Vector of the current control forces being applied to the spacecraft. */ + Vector m_ControlForces; + + /*! Pointer to the Environment forces function */ + ObjectFunctor m_EnvironmentForcesFunctor; + +// ************************* +// ******** HISTORY ******** +// ************************* +public: + /*! \brief Return a reference to the spacecraft's orbit history. + * + * This function is used to make evaluations on the spacecraft's orbit history. + * \code + * // Get the orbit state at t=30 seconds. + * OrbitState OrbState30 = myOrbit.GetHistoryObject().GetState(ssfTime(30)); + * \endcode + * @return reference (acts as a normal object, but actually "points" to the private data member) + * to the spacecraft's orbit history object. + */ + OrbitHistory& GetHistoryObject(); + +private: + OrbitHistory m_OrbitHistory; + +}; +/** @} */ // End of OrbitToolkit Group + +} // close namespace O_SESSAME +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Orbit.h,v $ +* Revision 1.10 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.9 2003/06/10 14:52:05 nilspace +* Changed GetHistory to GetHistoryObject +* +* Revision 1.8 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.7 2003/05/02 16:16:46 nilspace +* Documented the API. +* +* Revision 1.6 2003/04/28 20:13:18 nilspace +* GetHistory return by reference. +* +* Revision 1.5 2003/04/27 22:04:33 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/27 21:17:42 nilspace +* Finished moving function declarations out of the class interface. +* +* Revision 1.3 2003/04/27 21:14:01 nilspace +* Added to the namespace O_SESSAME. +* Moved function definitions outside of the class interface definition. +* +* Revision 1.2 2003/04/25 13:36:28 nilspace +* Updated to work with current History, Environment & Propagator objects. +* +* Revision 1.1 2003/04/08 22:48:59 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/orbit/OrbitState.cpp b/src/orbit/OrbitState.cpp new file mode 100644 index 0000000..05d39ed --- /dev/null +++ b/src/orbit/OrbitState.cpp @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitState.cpp +* \brief Implementation of the Orbit State Interface Class. +* \author $Author: nilspace $ +* \version $Revision: 1.9 $ +* \date $Date: 2003/06/12 23:08:20 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "OrbitState.h" +namespace O_SESSAME { + +OrbitState::OrbitState(): m_pOrbitStateRepresentation(NULL), m_pOrbitFrame(NULL) +{ + +} + +OrbitState::OrbitState(const OrbitState &_OrbStateCopy) +{ + /*! \todo Determine if the OrbitState copy function is req'd or hacked. */ + /*! \bug if OrbitFrame is not set, but a vector::push_back function is called, + * _OrbStateCopy.m_pOrbitFrame = 0xffffffff, which indicates a failure. Need + * to fix this. + */ + // If there is a current representation or frame, delete it to free the memory + // then copy the data members of the orbit state to be copied. + if(_OrbStateCopy.m_pOrbitStateRepresentation) + m_pOrbitStateRepresentation = _OrbStateCopy.m_pOrbitStateRepresentation->Clone(); + if(_OrbStateCopy.m_pOrbitFrame) + m_pOrbitFrame = _OrbStateCopy.m_pOrbitFrame->Clone(); + +} + +OrbitState::~OrbitState() +{ + /*! \todo determine how to delete OrbitState pointers */ +/* + if(m_pOrbitStateRepresentation) + delete m_pOrbitStateRepresentation; + if(m_pOrbitFrame) + delete m_pOrbitFrame; +*/ +} +OrbitState::OrbitState(OrbitStateRepresentation* _pOrbRep, OrbitFrame* _pOrbFrame) +{ + SetOrbitFrame(_pOrbFrame); + SetStateRepresentation(_pOrbRep); +} +void OrbitState::SetOrbitFrame(OrbitFrame* _pNewOrbitFrame) +{ /** \todo add conversion of OrbitStateRepresentation to the new frame */ + if(_pNewOrbitFrame) + { + if(m_pOrbitFrame) + delete m_pOrbitFrame; + m_pOrbitFrame = _pNewOrbitFrame->Clone(); + } + return; +} + +OrbitFrame* OrbitState::GetOrbitFrame() const +{ + return m_pOrbitFrame; +} +void OrbitState::SetStateRepresentation(OrbitStateRepresentation* _pStateRep) +{ + if(_pStateRep) + { + if(m_pOrbitStateRepresentation) + delete m_pOrbitStateRepresentation; + m_pOrbitStateRepresentation = _pStateRep->Clone(); + } +} + +void OrbitState::SetStateRepresentation(OrbitStateRepresentation* _pStateRep, OrbitFrame* _pOrbFrame) +{ + SetStateRepresentation(_pStateRep); + SetOrbitFrame(_pOrbFrame); +} + +OrbitStateRepresentation* OrbitState::GetStateRepresentation() const +{ + return m_pOrbitStateRepresentation; +} + +double OrbitState::GetOrbitAngularMomentum() const +{ + Vector Position(3); + Vector Velocity(3); + m_pOrbitStateRepresentation->GetPositionVelocity(Position, Velocity); + return norm2(skew(Position) * Velocity); +} + + +void OrbitState::SetState(const Vector &_State) +{ + if(m_pOrbitStateRepresentation) + m_pOrbitStateRepresentation->SetState(_State); + return; +} +Vector OrbitState::GetState() const +{ + if(m_pOrbitStateRepresentation) + return m_pOrbitStateRepresentation->GetState(); + else + return Vector(3); +} + +OrbitState OrbitState::operator= (const OrbitState& _OrbStateCopy) +{ + // If there is a current representation or frame, delete it to free the memory + // then copy the data members of the orbit state to be copied. + if(_OrbStateCopy.GetStateRepresentation()) + { + if( m_pOrbitStateRepresentation) + delete m_pOrbitStateRepresentation; + m_pOrbitStateRepresentation = _OrbStateCopy.GetStateRepresentation()->Clone(); + } + if(_OrbStateCopy.GetOrbitFrame()) + { + if(m_pOrbitFrame) + delete m_pOrbitFrame; + m_pOrbitFrame = _OrbStateCopy.GetOrbitFrame()->Clone(); + } + return (*this); +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitState.cpp,v $ +* Revision 1.9 2003/06/12 23:08:20 nilspace +* Fixed to calculate angular momentum. +* +* Revision 1.8 2003/06/12 18:02:15 nilspace +* Added GetAngularVelocity() function. +* +* Revision 1.7 2003/05/22 14:37:32 nilspace +* Return *this in operator= +* +* Revision 1.6 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.5 2003/05/13 18:46:28 nilspace +* Checked pointers if they were initialized before calling. +* +* Revision 1.4 2003/04/29 20:56:24 nilspace +* Update to work with Propagator. +* +* Revision 1.3 2003/04/29 18:47:31 nilspace +* Added copy constructor and operator= functions. +* +* Revision 1.2 2003/04/27 21:14:01 nilspace +* Added to the namespace O_SESSAME. +* Moved function definitions outside of the class interface definition. +* +* Revision 1.1 2003/04/25 14:01:28 nilspace +* Recommited to fix capitalization. +* +* Revision 1.1 2003/04/23 16:26:03 nilspace +* Updated directory structure & default parameters. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/OrbitState.h b/src/orbit/OrbitState.h new file mode 100644 index 0000000..14c8b47 --- /dev/null +++ b/src/orbit/OrbitState.h @@ -0,0 +1,204 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitState.h +* \brief Interface to the OrbitState class. +* \author $Author: rsharo $ +* \version $Revision: 1.10 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_STATE_H__ +#define __SSF_ORBIT_STATE_H__ + +#include "orbitframes/OrbitFrame.h" +#include "orbitstaterep/OrbitStateRepresentation.h" + +namespace O_SESSAME { + +/*! \brief Encapsulation of an Orbit State, including its coordinate type and reference frame. +* \ingroup OrbitToolkit +* +* \detail The OrbitState class is an abstract representation of a current orbital state, including +* its position and velocity (in some OrbitStateRepresentation) and respective frame (OrbitFrame). +* Each instance of OrbitState is a snapshot of the spacecraft at an instant in time. +* +* \par Example: + \code + OrbitState myOrbitState; + myOrbitState.SetStateRepresentation(new PositionVelocity); + myOrbitState.SetOrbitFrame(new OrbitFrameIJK); + Vector initPV(6); + // Space station + initPV(VectorIndexBase+0) = -5776.6; // km + initPV(VectorIndexBase+1) = -157; // km + initPV(VectorIndexBase+2) = 3496.9; // km + initPV(VectorIndexBase+3) = -2.595; // km/s + initPV(VectorIndexBase+4) = -5.651; // km/s + initPV(VectorIndexBase+5) = -4.513; // km/s + myOrbitState.SetState(initPV); + \endcode +* +* \todo should OrbitState contain an ssfTime object? +* \todo change to be a template class of the Representation Types +*/ +class OrbitState +{ +public: + /*! \brief Create an initially empty orbit state object */ + OrbitState(); + /*! \brief Default deconstructor. Deletes any unused variables. */ + virtual ~OrbitState(); + /*! \brief Create an orbit state from a copy of another orbit state. */ + OrbitState(const OrbitState &_OrbStateCopy); + + /*! \brief Create an orbit state object from a pointer to an orbit representation (positionVelocity, keplerian, etc), and orbit frame (IJK, PQW, etc.) + * @param _pOrbRep the orbit representation (positionVelocity vector, keplerian elements, etc.) to store in the state. + * @param _pOrbFrame the orbit frame (IJK, SEZ, PQW, etc) that is the reference frame of the representation. + */ + OrbitState(OrbitStateRepresentation* _pOrbRep, OrbitFrame* _pOrbFrame = NULL); + + /*! \brief Set (or Change) the stored orbit frame that is the reference for the represenation. + * + * \detail In the future, this will convert the orbit representation from the previous frame (if defined) to the new frame. + * \todo Implement the orbit representation conversion due to an orbit frame change. + * @param _pnewOrbitFrame pointer to the orbit frame to set or convert the orbit representation to. + */ + void SetOrbitFrame(OrbitFrame* _pnewOrbitFrame); + + /*! \brief Returns the pointer to the current reference frame of the orbit state. + * @return pointer to the current reference frame + */ + OrbitFrame* GetOrbitFrame() const; + + /*! \brief Set (or change) the orbit state's representation. + * @param _pStateRep pointer to the new orbit state representation. + */ + void SetStateRepresentation(OrbitStateRepresentation* _pStateRep); + + /*! \brief Set (or change) the orbit state's representation and reference frame. + * @param _pStateRep pointer to the new orbit state representation. + * @param _pOrbFrame pointer to the orbit frame to set or convert the orbit representation to. + */ + void SetStateRepresentation(OrbitStateRepresentation* _pStateRep, OrbitFrame* _pOrbFrame); + + /*! \brief Return a pointer to the orbit state's current state representation. + * @return pointer to the current representation (positionVelocity vector, keplerian elements, etc.) + */ + OrbitStateRepresentation* GetStateRepresentation() const; + + /*! \brief Calculates the orbit angular momentum at the current orbit state. + * + * \f[ {\bf} h = |{\bf r} \times {\bf v}| \f] + * @return the orbit angular momentum. + */ + double GetOrbitAngularMomentum() const; + + /*! \brief internally set the orbit representation's state. + * \warning Depracated - do not use - will be moving to private. + * @param _state Vector of the state components that are the same type of the orbit state representation. + */ + void SetState(const Vector& _state); + + /*! \brief internally set the orbit representation's state and reference frame. + * \warning Depracated - do not use - will be moving to private. + * @param _state Vector of the state components that are the same type of the orbit state representation. + * @param _pOrbFrame pointer to the orbit frame to set or convert the orbit representation to. + */ + void SetState(const Vector& _state, OrbitFrame* _pOrbFrame); + + /*! \brief internally return the orbit representation's state Vector. + * \warning Depracated - do not use - will be moving to private. + * @return Vector of the state components that are the same type of the orbit state representation. + */ + Vector GetState() const; + + /*! \brief Copy an instance of OrbitState. + * @param _OrbStateCopy right operand that is the original orbit state to be copied. + * @return a copy of the orbit state. + */ + OrbitState operator= (const OrbitState& _OrbStateCopy); +private: + /*! \brief internal pointer to the current orbit state representation */ + OrbitStateRepresentation* m_pOrbitStateRepresentation; + /*! \brief internal pointer to the current orbit state reference frame */ + OrbitFrame* m_pOrbitFrame; +}; + +/* Possibility of turning into a template class +OrbitState initialOrbit1; +OrbitState initialOrbit1.ChangeType(); +vs. +OrbitState initOrb1(POSITION_VELOCITY, ORBFRAME_IJK); +initOrb1.ChangeType(KEPLERIAN); +initOrb1.GetKeplerianElements(); + +template +class OrbitState +{ +public: + OrbitState(); + virtual ~OrbitState(); + OrbitState(const Vector& _State); + +// void SetOrbitFrame(const TOrbFrame &_newOrbitFrame); + const TOrbFrame& GetOrbitFrame() const; + +// void SetStateRepresentation(const TOrbRep &_StateRep); +// void SetStateRepresentation(const TOrbRep &_StateRep, const TOrbFrame &_orbFrame); + const TOrbRep& GetStateRepresentation() const; + + void SetState(const Vector &_state); + const Vector& GetState() const; + +private: + TOrbRep m_OrbitStateRepresentation; + TOrbFrame m_OrbitFrame; + +}; +*/ +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitState.h,v $ +* Revision 1.10 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.9 2003/06/12 23:08:20 nilspace +* Fixed to calculate angular momentum. +* +* Revision 1.8 2003/06/12 18:02:15 nilspace +* Added GetAngularVelocity() function. +* +* Revision 1.7 2003/05/22 14:33:58 nilspace +* Added NULL default value to constructor. +* +* Revision 1.6 2003/05/13 18:46:29 nilspace +* Checked pointers if they were initialized before calling. +* +* Revision 1.5 2003/05/02 16:16:46 nilspace +* Documented the API. +* +* Revision 1.4 2003/04/29 20:56:25 nilspace +* Update to work with Propagator. +* +* Revision 1.3 2003/04/29 18:47:31 nilspace +* Added copy constructor and operator= functions. +* +* Revision 1.2 2003/04/23 16:26:02 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.1 2003/04/08 22:47:00 nilspace +* Initial Submission. +* +* +* +******************************************************************************/ diff --git a/src/orbit/orbit.pro b/src/orbit/orbit.pro new file mode 100644 index 0000000..850a30c --- /dev/null +++ b/src/orbit/orbit.pro @@ -0,0 +1,35 @@ +# +# $Id: orbit.pro,v 1.3 2003/10/18 21:37:28 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = Orbit.h OrbitState.h\ + orbitstaterep/OrbitStateRepresentation.h\ + orbitstaterep/PositionVelocity.h\ + orbitstaterep/Keplerian.h\ + orbitframes/OrbitFrame.h +SOURCES = Orbit.cpp OrbitState.cpp\ + orbitstaterep/OrbitStateRepresentation.cpp\ + orbitstaterep/PositionVelocity.cpp\ + orbitstaterep/Keplerian.cpp\ + orbitframes/OrbitFrame.cpp + +TARGET = osessame_orbit +VERSION = 1.0 + +DESTDIR = ../../lib/ +INCLUDEPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment .. +CONFIG = console staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment ../utils diff --git a/src/orbit/orbitframes/CVS/Entries b/src/orbit/orbitframes/CVS/Entries new file mode 100644 index 0000000..600cf84 --- /dev/null +++ b/src/orbit/orbitframes/CVS/Entries @@ -0,0 +1,11 @@ +/OrbitFrame.cpp/1.2/Tue Apr 29 18:45:29 2003// +/OrbitFrame.h/1.9/Tue May 20 17:47:59 2003// +/OrbitFrameECEF.cpp/1.1/Fri Apr 25 13:38:03 2003// +/OrbitFrameECEF.h/1.2/Tue May 20 17:47:59 2003// +/OrbitFrameEQW.h/1.7/Tue May 20 17:47:59 2003// +/OrbitFrameIJK.h/1.7/Tue May 20 17:47:59 2003// +/OrbitFrameNTW.h/1.6/Tue Apr 29 20:17:39 2003// +/OrbitFramePQW.h/1.8/Wed May 21 03:51:38 2003// +/OrbitFrameRSW.h/1.7/Wed May 21 03:51:38 2003// +/OrbitFrameSEZ.h/1.2/Tue May 20 17:47:59 2003// +D diff --git a/src/orbit/orbitframes/CVS/Repository b/src/orbit/orbitframes/CVS/Repository new file mode 100644 index 0000000..76b151e --- /dev/null +++ b/src/orbit/orbitframes/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/orbit/orbitframes diff --git a/src/orbit/orbitframes/CVS/Root b/src/orbit/orbitframes/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/orbit/orbitframes/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/orbit/orbitframes/OrbitFrame.cpp b/src/orbit/orbitframes/OrbitFrame.cpp new file mode 100644 index 0000000..44369ed --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrame.cpp @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrame.cpp +* \brief Implementation of the Orbit Frame Class. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/04/29 18:45:29 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "OrbitFrame.h" + + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrame.cpp,v $ +* Revision 1.2 2003/04/29 18:45:29 nilspace +* Moved all function definitions out of class interface definition. +* +* Revision 1.1 2003/04/08 22:48:03 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFrame.h b/src/orbit/orbitframes/OrbitFrame.h new file mode 100644 index 0000000..42ca4a6 --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrame.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrame.h +* \brief Interface to the Orbit Frame abstract Class. +* \author $Author: nilspace $ +* \version $Revision: 1.9 $ +* \date $Date: 2003/05/20 17:47:59 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_H__ +#define __SSF_ORBIT_FRAME_H__ +#include "Rotation.h" + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \defgroup OrbitFrames Orbit Frames +* \ingroup OrbitToolkit +* +* \detail +*/ + +/*! \brief Abstract class representating an orbital reference frame. +* \ingroup OrbitFrames +* +* \detail +*/ + +class OrbitFrame +{ +public: + virtual Rotation GetRotation2IJK() const = 0; + virtual Rotation GetRotationFromIJK() const = 0; + virtual OrbitFrame* NewPointer() = 0; + virtual OrbitFrame* Clone() = 0; + virtual ~OrbitFrame(); + +protected: + OrbitFrame(); + OrbitFrame(const Rotation &_Transformation); +private: + /** pointer to the origin object */ +// void *m_Origin; +// m_FundamentalPlane; +// m_PreferredDirection; + RotationSense m_Sense; + Rotation m_Transformation2IJK; + +}; + +inline OrbitFrame::OrbitFrame(): m_Sense(RIGHT_HAND) {}; +inline OrbitFrame::OrbitFrame(const Rotation &_Transformation) : m_Sense(RIGHT_HAND), m_Transformation2IJK(_Transformation) {}; +inline OrbitFrame::~OrbitFrame() {}; + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrame.h,v $ +* Revision 1.9 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.8 2003/04/29 20:17:39 nilspace +* Added NewPointer() and Clone() functions. +* +* Revision 1.7 2003/04/29 18:45:30 nilspace +* Moved all function definitions out of class interface definition. +* +* Revision 1.6 2003/04/27 21:14:02 nilspace +* Added to the namespace O_SESSAME. +* Moved function definitions outside of the class interface definition. +* +* Revision 1.5 2003/04/25 14:02:41 nilspace +* Made the destructor public. +* +* Revision 1.4 2003/04/24 20:05:54 nilspace +* Made GetRotation functions const. +* +* Revision 1.3 2003/04/23 16:26:05 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.2 2003/04/22 17:37:24 nilspace +* Added reference frames. +* +* Revision 1.1 2003/04/08 22:48:03 nilspace +* Initial Submission. +* +* +* +******************************************************************************/ diff --git a/src/orbit/orbitframes/OrbitFrameECEF.cpp b/src/orbit/orbitframes/OrbitFrameECEF.cpp new file mode 100644 index 0000000..3217d76 --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrameECEF.cpp @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrameECEF.cpp +* \brief Implementation of the ECEF Satellite Coordinate System Class. +* \author $Author: nilspace $ +* \version $Revision: 1.1 $ +* \date $Date: 2003/04/25 13:38:03 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "OrbitFrameECEF.h" + +OrbitFrameECEF::OrbitFrameECEF() +{ +} + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrameECEF.cpp,v $ +* Revision 1.1 2003/04/25 13:38:03 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFrameECEF.h b/src/orbit/orbitframes/OrbitFrameECEF.h new file mode 100644 index 0000000..2abef4e --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrameECEF.h @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrameECEF.h +* \brief Interface to the ECEF Satellite Coordinate System Class. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/05/20 17:47:59 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_ECEF_H__ +#define __SSF_ORBIT_FRAME_ECEF_H__ + +/*! \brief Earth-Centered, Earth-Fixed Satellite Coordinate System +* \ingroup OrbitFrames +* +* Detailed Description. +*/ +class OrbitFrameECEF : public OrbitFrame +{ +public: + /*! \brief Constructor + * @param _ApparentSiderealTime Apparent Sidereal Time (rad) + */ + OrbitFrameECEF(const double &_ApparentSiderealTime):OrbitFrame(R3(-_ApparentSiderealTime)); + + /*! \brief Return the rotation \f$R^{IJK-ECEF}\f$ + * \detail ignores transformation due to precession, nutation, and polar motion. + * \f$\vec{r}_{IJK} = R_{3}\left(-\theta_{AST}\right)\vec{r}_{ECEF}\f$ + * @param _ApparentSiderealTime Apparent Sidereal Time (rad) + * @return rotation from ECEF to IJK + */ + Rotation GetRotation2IJK() const {return m_Transformation2IJK;}; + + /*! \brief Return the rotation \f$R^{ECEF-IJK}\f$ + * \detail ignores transformation due to precession, nutation, and polar motion. + * \f$\vec{r}_{ECEF} = R_{3}\left(\theta_{AST}\right)\vec{r}_{IJK}\f$ + * @param _ApparentSiderealTime Apparent Sidereal Time (rad) + * @return rotation from IJK to ECEF + */ + Rotation GetRotationFromIJK() const {return ~m_Transformation2IJK;}; + +protected: + +private: + +}; + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrameECEF.h,v $ +* Revision 1.2 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.1 2003/04/25 13:38:04 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFrameEQW.h b/src/orbit/orbitframes/OrbitFrameEQW.h new file mode 100644 index 0000000..6cbb82c --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrameEQW.h @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrameEQW.h +* \brief Interface to the EQW Orbit Frame Class. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/05/20 17:47:59 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_EQW_H__ +#define __SSF_ORBIT_FRAME_EQW_H__ +#include "OrbitFrame.h" + +/*! \brief Equinoctial Coordinate System +* \ingroup OrbitFrames +* +* \detail Detailed Description +*/ +class OrbitFrameEQW : public OrbitFrame +{ +public: +{ + /*! \brief Constructor + * @param _LongAscNode Longitude of the Ascending Node (rad) + * @param _Inclination Inclination (rad) + */ + OrbitFrameEQW(const double &_LongAscNode, const double &_Inclination); + + /*! \brief Deconstructor */ + virtual ~OrbitFrameEQW(); + + /*! \brief Return the rotation \f$R^{IJK-SEZ}\f$ + * \f${\bf r}_{IJK} = R_{3}\left(-\theta_{LST}\right)R_{2}\left(\theta_{LST}-\pi\right){\bf r}_{ECEF}\f$ + * @return rotation from SEZ to IJK + */ + Rotation GetRotation2IJK() const; + + /*! \brief Return the rotation \f$R^{ECEF-SEZ}\f$ + * \f${\bf r}_{ECEF} = R_{2}\left(\pi-\theta_{LST}\right)R_{3}\left(\theta_{LST}\right){\bf r}_{IJK}\f$ + * @return rotation from IJK to SEZ + */ + Rotation GetRotationFromIJK() const; + + OrbitFrameEQW* NewPointer(); + OrbitFrameEQW* Clone(); + +protected: + int m_fr; +private: + +}; +inline OrbitFrameEQW::OrbitFrameEQW(const double &_LongAscNode, const double &_Inclination) + { + if(_Inclination>0 && _Inclination<=PI/2) {m_fr = 1;} + else{m_fr = -1;} + m_Transformation2IJK = R3(-m_fr*m_LongAscNode)*R1(-m_Inclination)*R3(m_LongAscNode); + }; +inline OrbitFrameEQW::~OrbitFrameEQW() {}; +inline Rotation OrbitFrameEQW::GetRotation2IJK() const {return m_Transformation2IJK;}; +inline Rotation OrbitFrameEQW::GetRotationFromIJK() const {return ~m_Transformation2IJK;}; + +inline OrbitFrameEQW* OrbitFrameEQW::NewPointer() { return new OrbitFrameEQW(); } +inline OrbitFrameEQW* OrbitFrameEQW::Clone() { return new OrbitFrameEQW(*this); } +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrameEQW.h,v $ +* Revision 1.7 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.6 2003/04/29 20:17:39 nilspace +* Added NewPointer() and Clone() functions. +* +* Revision 1.5 2003/04/29 18:45:31 nilspace +* Moved all function definitions out of class interface definition. +* +* Revision 1.4 2003/04/24 20:05:55 nilspace +* Made GetRotation functions const. +* +* Revision 1.3 2003/04/23 16:26:05 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.2 2003/04/22 17:37:25 nilspace +* Added reference frames. +* +* Revision 1.1 2003/04/08 22:48:03 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFrameIJK.h b/src/orbit/orbitframes/OrbitFrameIJK.h new file mode 100644 index 0000000..d8589f1 --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrameIJK.h @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrameIJK.h +* \brief Interface to the Geocentric Orbit Coordinate System Class. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/05/20 17:47:59 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_IJK_H__ +#define __SSF_ORBIT_FRAME_IJK_H__ +#include "Rotation.h" +#include "OrbitFrame.h" +/*! \brief Geocentric Orbit Coordinate System +* \ingroup OrbitFrames +* +* \detail Detailed Description. +*/ +class OrbitFrameIJK : public OrbitFrame +{ +public: + OrbitFrameIJK(); + virtual ~OrbitFrameIJK(); + Rotation GetRotation2IJK() const; + Rotation GetRotationFromIJK() const; + + OrbitFrameIJK* NewPointer(); + /*! \brief Returns a pointer to a copy of the Orbit Frame + * + * \detail Since orbit frames don't change, the function actually just returns a new pointer since + * its cheaper than copying useless information. + */ + OrbitFrameIJK* Clone(); +protected: + + +private: + +}; +inline OrbitFrameIJK::OrbitFrameIJK() {}; +inline OrbitFrameIJK::~OrbitFrameIJK() {}; +inline Rotation OrbitFrameIJK::GetRotation2IJK() const {return eye(3);}; +inline Rotation OrbitFrameIJK::GetRotationFromIJK() const {return eye(3);}; +inline OrbitFrameIJK* OrbitFrameIJK::NewPointer() { return new OrbitFrameIJK(); } +inline OrbitFrameIJK* OrbitFrameIJK::Clone() { return new OrbitFrameIJK(/**this*/); } +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrameIJK.h,v $ +* Revision 1.7 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.6 2003/04/29 20:17:39 nilspace +* Added NewPointer() and Clone() functions. +* +* Revision 1.5 2003/04/29 18:45:31 nilspace +* Moved all function definitions out of class interface definition. +* +* Revision 1.4 2003/04/24 20:05:55 nilspace +* Made GetRotation functions const. +* +* Revision 1.3 2003/04/23 16:26:05 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.2 2003/04/22 17:37:25 nilspace +* Added reference frames. +* +* Revision 1.1 2003/04/08 22:48:04 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFrameNTW.h b/src/orbit/orbitframes/OrbitFrameNTW.h new file mode 100644 index 0000000..bb2e11e --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrameNTW.h @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrameNTW.h +* \brief Interface to the NTW Satellite Coordinate System Class. +* \author $Author: nilspace $ +* \version $Revision: 1.6 $ +* \date $Date: 2003/04/29 20:17:39 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_NTW_H__ +#define __SSF_ORBIT_FRAME_NTW_H__ +#include "OrbitFrame.h" + +/*! \brief NTW Satellite Coordinate System +* +* Detailed Description. The primary axis lies in the orbital plane, normal to the velocity +* vector. The T axis is tangential to the orbit, and the W axis is normal to the orbital plane. +* In-track: deviations along the T axis. +* Used mainly to analyze drag effects on the orbit because drag always acts along the velocity +* vector. Also referred to as the Frenet System. (Vallado, pg. 43-44) +*/ +class OrbitFrameNTW : public OrbitFrame +{ + /*! \brief Constructor + * @param _LongAscNode Longitude of the Ascending Node (rad) + * @param _Inclination Inclination (rad) + * @param _ArgPerigee Argument of Perigee (rad) + * @param _ArgLatitude Argument of Latitude (rad) + */ + OrbitFrameNTW(const double &_LongAscNode, const double &_Inclination, const double &_ArgPerigee, const double &_ArgLatitude); + + /*! \brief Deconstructor */ + virtual ~OrbitFrameNTW(); + + /*! \brief Return the rotation \f$R^{NTW-IJK}\f$ + * \f${\bf r}_{IJK} = R_{3}(-\Omega)R_{1}(-i)R_{3}(-u)R_{3}(-\phi_{fpa}){\bf r}_{NTW}\f$ + * @return rotation from NTW to IJK + */ + Rotation GetRotation2IJK() const; + + /*! \brief Return the rotation \f$R^{IJK-NTW}\f$ + * \f${\bf r}_{NTW} = R_{3}(\phi_{fpa})R_{3}(u)R_{1}(i)R_{3}(\Omega){\bf r}_{IJK}\f$ + * @return rotation from IJK to NTW + */ + Rotation GetRotationFromIJK() const; + + OrbitFrameNTW* NewPointer(); + OrbitFrameNTW* Clone(); +protected: + +private: + +}; +inline OrbitFrameNTW::OrbitFrameNTW(const double &_LongAscNode, const double &_Inclination, const double &_ArgPerigee, const double &_ArgLatitude): OrbitFrame(R3(-_LongAscNode)*R1(-_Inclination)*R3(-_ArgPerigee)*R3(-_ArgLatitude)) {}; +inline OrbitFrameNTW::~OrbitFrameNTW() {}; + +inline Rotation OrbitFrameNTW::GetRotation2IJK() const {return m_Transformation2IJK;}; +inline Rotation OrbitFrameNTW::GetRotationFromIJK() const {return ~m_Transformation2IJK;}; +inline OrbitFrameNTW* OrbitFrameNTW::NewPointer() { return new OrbitFrameNTW(); } +inline OrbitFrameNTW* OrbitFrameNTW::Clone() { return new OrbitFrameNTW(*this); } +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrameNTW.h,v $ +* Revision 1.6 2003/04/29 20:17:39 nilspace +* Added NewPointer() and Clone() functions. +* +* Revision 1.5 2003/04/29 18:45:35 nilspace +* Moved all function definitions out of class interface definition. +* +* Revision 1.4 2003/04/24 20:05:55 nilspace +* Made GetRotation functions const. +* +* Revision 1.3 2003/04/23 16:26:06 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.2 2003/04/22 17:37:25 nilspace +* Added reference frames. +* +* Revision 1.1 2003/04/08 22:48:04 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFramePQW.h b/src/orbit/orbitframes/OrbitFramePQW.h new file mode 100644 index 0000000..cd6b1fb --- /dev/null +++ b/src/orbit/orbitframes/OrbitFramePQW.h @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFramePQW.h +* \brief Interface to the Perifocal Satellite Coordinate System Class. +* \author $Author: nilspace $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/05/21 03:51:38 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_PQW_H__ +#define __SSF_ORBIT_FRAME_PQW_H__ +#include "OrbitFrame.h" + +/*! \brief Satellite Radial Coordinate System +* \ingroup OrbitFrames +* +* \detail The fundamental plane is the satellite's orbit, and the origin is at the +* center of the Earth. The P axis points towards perigee, and the Q axis is \f$90^{\circ}\f$ +* from the P axis in the direction of satellite motion. The W axis is then normal to the orbit. +* The PQW system always maintains an orientation towards perigee and is therefore best +* suited for robits with a well-defined eccentricity. (Vallado, pg 41) +* +*/ +class OrbitFramePQW : public OrbitFrame +{ + /*! \brief Constructor + * @param _LongAscNode Longitude of the Ascending Node (rad) + * @param _Inclination Inclination (rad) + * @param _ArgPerigee Argument of Perigee (rad) + */ + OrbitFramePQW(const double &_LongAscNode, const double &_Inclination, const double &_ArgPerigee); + + /*! \brief Deconstructor */ + virtual ~OrbitFramePQW(); + /*! \brief Return the rotation \f$R^{PQW-IJK}\f$ + * \f${\bf r}_{IJK} = R_{3}\left(-\Omega\right)R_{1}\left(-i\right)R_{3}\left(-\omega\right){\bf r}_{ECEF}\f$ + * @return rotation from PQW to IJK + */ + Rotation GetRotation2IJK() const; + + /*! \brief Return the rotation \f$R^{IJK-PQW}\f$ + * \f${\bf r}_{ECEF} = R_{3}\left(\omega\right)R_{1}\left(i\right)R_{3}\left(\Omega\right){\bf r}_{IJK}\f$ + * @return rotation from IJK to PQW + */ + Rotation GetRotationFromIJK() const; + + OrbitFramePQW* NewPointer(); + OrbitFramePQW* Clone(); +protected: + +private: + +}; +inline OrbitFramePQW::OrbitFramePQW(const double &_LongAscNode, const double &_Inclination, const double &_ArgPerigee): OrbitFrame(R3(-_LongAscNode)*R1(-_Inclination)*R3(-_ArgPerigee)) {}; +inline OrbitFramePQW::~OrbitFramePQW() {}; + +inline Rotation OrbitFramePQW::GetRotation2IJK() const {return m_Transformation2IJK;}; +inline Rotation OrbitFramePQW::GetRotationFromIJK() const {return ~m_Transformation2IJK;}; +inline OrbitFramePQW* OrbitFrameIJK::NewPointer() { return new OrbitFramePQW(); } +inline OrbitFramePQW* OrbitFrameIJK::Clone() { return new OrbitFramePQW(*this); } + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFramePQW.h,v $ +* Revision 1.8 2003/05/21 03:51:38 nilspace +* Fixed spelling of "the" in comments. +* +* Revision 1.7 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.6 2003/04/29 20:17:40 nilspace +* Added NewPointer() and Clone() functions. +* +* Revision 1.5 2003/04/29 18:45:35 nilspace +* Moved all function definitions out of class interface definition. +* +* Revision 1.4 2003/04/24 20:05:55 nilspace +* Made GetRotation functions const. +* +* Revision 1.3 2003/04/23 16:26:06 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.2 2003/04/22 17:37:25 nilspace +* Added reference frames. +* +* Revision 1.1 2003/04/08 22:48:04 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFrameRSW.h b/src/orbit/orbitframes/OrbitFrameRSW.h new file mode 100644 index 0000000..25966a0 --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrameRSW.h @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrameRSW.h +* \brief Interface to the RSW Satellite Coordinate System Class. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/05/21 03:51:38 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_RSW_H__ +#define __SSF_ORBIT_FRAME_RSW_H__ +#include "OrbitFrame.h" + +/*! \brief RSW Satellite Coordinate System +* \ingroup OrbitFrames +* +* \detail Applies to studies of relative motion because the system moves +* with the satellite. The R axis is defined as pointing from the Earth's center along the +* radius vector toward the satellite, and the W axis is fixed along the direction normal to +* orbital plane. The S axis points in the direction of the velocity vector and is perpendicular +* to the radius vector. +* Radial: positions and displacements are parallel to the position vector (along R axis) +* Along-track: displacements are normal to the position vector and (for small e) are nearly +* parallel to the satellite's instantaneous velocity vector (along the S axis) +* Cross-track: positions are normal to the plane defined by thte current position and +* velocity vectors (along the W axis). +* Sometimes called the Gaussian coordinate system. (Vallado, pg. 42-43) +*/ +class OrbitFrameRSW : public OrbitFrame +{ +public: + OrbitFrameRSW(); + virtual ~OrbitFrameRSW(); + + OrbitFramePQW* NewPointer(); + OrbitFramePQW* Clone(); +protected: + + +private: + +}; +inline OrbitFrameRSW::OrbitFrameRSW() {}; +inline OrbitFrameRSW::~OrbitFrameRSW() {}; +inline OrbitFrameRSW* OrbitFrameRSW::NewPointer() { return new OrbitFrameRSW(); } +inline OrbitFrameRSW* OrbitFrameRSW::Clone() { return new OrbitFrameRSW(*this); } + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrameRSW.h,v $ +* Revision 1.7 2003/05/21 03:51:38 nilspace +* Fixed spelling of "the" in comments. +* +* Revision 1.6 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.5 2003/04/29 20:17:40 nilspace +* Added NewPointer() and Clone() functions. +* +* Revision 1.4 2003/04/29 18:45:35 nilspace +* Moved all function definitions out of class interface definition. +* +* Revision 1.3 2003/04/23 16:26:07 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.2 2003/04/22 17:37:25 nilspace +* Added reference frames. +* +* Revision 1.1 2003/04/08 22:48:04 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitframes/OrbitFrameSEZ.h b/src/orbit/orbitframes/OrbitFrameSEZ.h new file mode 100644 index 0000000..e5bb043 --- /dev/null +++ b/src/orbit/orbitframes/OrbitFrameSEZ.h @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitFrameSEZ.h +* \brief Interface to the SEZ Satellite Coordinate System Class. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/05/20 17:47:59 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_FRAME_SEZ_H__ +#define __SSF_ORBIT_FRAME_SEZ_H__ +#include "OrbitFrame.h" + +/*! \brief Topocentric Horizon, SEZ, Satellite Coordinate System +* \ingroup OrbitFrames +* +* \detail Detailed Description. +*/ +class OrbitFrameSEZ : public OrbitFrame +{ + /*! \brief Constructor + * @param _LocalSiderealTime Apparent Sidereal Time (rad) + * @param _GeodeticLatitude Geodetic Latitude (rad) + */ + OrbitFrameSEZ(const double &_LocalSiderealTime, const double &_GeodeticLatitude): OrbitFrame(R3(-m_LocalSiderealTime)*R2(m_GeodeticLatitude-PI/2)); + + /*! \brief Deconstructor */ + ~OrbitFrameSEZ() {}; + + /*! \brief Return the rotation \f$R^{SEZ-IJK}\f$ + * \f${\bf r}_{IJK} = R_{3}\left(-\theta_{LST}\right)R_{2}\left(\theta_{LST}-\pi\right){\bf r}_{ECEF}\f$ + * @return rotation from SEZ to IJK + */ + Rotation GetRotation2IJK() const {return m_Transformation2IJK;}; + + /*! \brief Return the rotation \f$R^{IJK-SEZ}\f$ + * \f${\bf r}_{ECEF} = R_{2}\left(\pi-\theta_{LST}\right)R_{3}\left(\theta_{LST}\right){\bf r}_{IJK}\f$ + * @return rotation from IJK to SEZ + */ + Rotation GetRotationFromIJK() const {return ~m_Transformation2IJK;}; + +protected: + +private: + +}; + + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitFrameSEZ.h,v $ +* Revision 1.2 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.1 2003/04/25 13:38:04 nilspace +* Initial Submission. +* +* Revision 1.1 2003/04/08 22:48:04 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitmodels/CVS/Entries b/src/orbit/orbitmodels/CVS/Entries new file mode 100644 index 0000000..ebe817b --- /dev/null +++ b/src/orbit/orbitmodels/CVS/Entries @@ -0,0 +1,2 @@ +/TwoBodyDynamics.h/1.8/Sat Oct 18 21:37:28 2003// +D diff --git a/src/orbit/orbitmodels/CVS/Repository b/src/orbit/orbitmodels/CVS/Repository new file mode 100644 index 0000000..fab184c --- /dev/null +++ b/src/orbit/orbitmodels/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/orbit/orbitmodels diff --git a/src/orbit/orbitmodels/CVS/Root b/src/orbit/orbitmodels/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/orbit/orbitmodels/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/orbit/orbitmodels/TwoBodyDynamics.h b/src/orbit/orbitmodels/TwoBodyDynamics.h new file mode 100644 index 0000000..b55c47e --- /dev/null +++ b/src/orbit/orbitmodels/TwoBodyDynamics.h @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file TwoBodyDynamics.h +* \brief Dynamic equations and forces of two-body motion. +* \author $Author: rsharo $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_TWOBODYDYNAMICS_H__ +#define __OSESSAME_TWOBODYDYNAMICS_H__ +#include "matrix/Matrix.h" +#include "Integrator.h" +#include "utils/Time.h" +#include "Orbit.h" +#include "OrbitState.h" +#include "Attitude.h" +#include +using namespace std; +using namespace O_SESSAME; + +/*! \brief Orbit state conversion function from Position and Velocity state vector. +* \relates TwoBodyDynamics +* +* This function converts a matrix of states from the TwoBodyDynamics right-hand +* side function into an OrbitState object. This conversion function is necessary for propagators +* to store to an OrbitHistory object regardless of the equations of motion state vector being +* used. +* @param _meshPoint State vector from integration mesh point, [Position (3), Velocity (3)]. +* @param _convertedOrbitState OrbitState object that is converted from the mesh point vector. This function +* just sets the position and velocity state representation and requires the user to set the +* corresponding reference frame. +*/ +static void PositionVelocityConvFunc(const Matrix &_meshPoint, OrbitState &_convertedOrbitState) +{ + static Vector tempPosVelVector(_meshPoint[MatrixColsIndex].getIndexBound() - 1); + tempPosVelVector(_) = ~_meshPoint(_,_(MatrixIndexBase+1, _meshPoint[MatrixColsIndex].getIndexBound())); + _convertedOrbitState.GetStateRepresentation()->SetPositionVelocity(tempPosVelVector); + return; +} + +/*! \brief Orbit equation of motion using position and velocity. +* @ingroup OrbitEquationsOfMotion +* +* +* Calculate the new time rate of change of state (position & velocity) using two-body dynamics with disturbance forces +\f[ +\ddot{\vec{r}} = -\frac{\mu}{r^{2}}\frac{\vec{r}}{r}\f] +The returned state vector is: +\f[ +\begin{bmatrix} +\dot{\vec{r}}\\ +\dot{\vec{v}} +\end{bmatrix} + = +\begin{bmatrix} +\vec{v}\\ +-\frac{\mu}{\left|\vec{r}\right|^{3}}\vec{r} +\end{bmatrix} +\f] +* @param _time current time (in seconds) +* @param _state vector of states, \f$\left[\vec{r},\vec{v}\right]^{T}\f$ (kilometers, kilometers/second) +* @param _pOrbit pointer to the current Orbit instance +* @param _pAttitude pointer to the current Attitude instance +* @param _parameters additional parameters for integration \f$\left[\mu\right]\f$ +* @param _forceFuncPtr pointer to the force calculating function +* @return 6x1 vector of time derivatives of state \f$\left[\dot{\vec{r}},\dot{\vec{v}}\right]^{T}\f$ +*/ +static Vector TwoBodyDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ +// _Orbit->SetStateObject(OrbitState(new PositionVelocity(_integratingState))); + static Vector Forces(3); + static Vector Velocity(3); + static Vector stateDot(6); + static AttitudeState tempAttState; // don't need this except to pass an empty one if there is no attitude + static OrbitState orbState(new PositionVelocity); + + orbState.GetStateRepresentation()->SetPositionVelocity(_integratingState); + + if(_pAttitude) + Forces = _forceFunctorPtr.Call(_time, orbState, _pAttitude->GetStateObject()); + else + Forces = _forceFunctorPtr.Call(_time, orbState, tempAttState); + + Velocity(_) = _integratingState(_(VectorIndexBase+3,VectorIndexBase+5)); + + + stateDot(_(VectorIndexBase, VectorIndexBase+2)) = Velocity(_); + stateDot(_(VectorIndexBase+3, VectorIndexBase+5)) = Forces(_); + return stateDot; +} + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: TwoBodyDynamics.h,v $ +* Revision 1.8 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.7 2003/06/12 18:02:37 nilspace +* Fixed evaluation. +* +* Revision 1.6 2003/05/22 21:03:26 nilspace +* Fixed to run faster with static variables. +* +* Revision 1.5 2003/05/20 17:47:59 nilspace +* Updated comments. +* +* Revision 1.4 2003/05/13 18:49:41 nilspace +* Fixed to get the StateObjects. +* +* Revision 1.3 2003/05/10 00:43:13 nilspace +* Updated the includes for Orbit.h and Attitude.h +* +* Revision 1.2 2003/04/22 20:25:44 simpliciter +* Updated LaTeX formulas for \ddot{r} and \dot{state vector} for +* proper display. +* +* Revision 1.1 2003/04/08 22:48:29 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/orbit/orbitstaterep/CVS/Entries b/src/orbit/orbitstaterep/CVS/Entries new file mode 100644 index 0000000..110e3fa --- /dev/null +++ b/src/orbit/orbitstaterep/CVS/Entries @@ -0,0 +1,7 @@ +/Keplerian.cpp/1.10/Fri May 23 19:28:32 2003// +/Keplerian.h/1.12/Sun Aug 24 20:59:13 2003// +/OrbitStateRepresentation.cpp/1.1/Tue Apr 8 22:47:35 2003// +/OrbitStateRepresentation.h/1.9/Sat Oct 18 21:37:28 2003// +/PositionVelocity.cpp/1.4/Tue Apr 29 18:48:31 2003// +/PositionVelocity.h/1.7/Tue May 13 18:47:56 2003// +D diff --git a/src/orbit/orbitstaterep/CVS/Repository b/src/orbit/orbitstaterep/CVS/Repository new file mode 100644 index 0000000..c9b245f --- /dev/null +++ b/src/orbit/orbitstaterep/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/orbit/orbitstaterep diff --git a/src/orbit/orbitstaterep/CVS/Root b/src/orbit/orbitstaterep/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/orbit/orbitstaterep/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/orbit/orbitstaterep/Keplerian.cpp b/src/orbit/orbitstaterep/Keplerian.cpp new file mode 100644 index 0000000..b3ac72e --- /dev/null +++ b/src/orbit/orbitstaterep/Keplerian.cpp @@ -0,0 +1,652 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Keplerian.cpp + * \brief Implementation of the Keplerian orbit state representation. + * \author $Author: simpliciter $ + * \version $Revision: 1.10 $ + * \date $Date: 2003/05/23 19:28:32 $ + *////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * + */ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Keplerian.h" +namespace O_SESSAME { + +/*! \brief Default Deconstructor */ +Keplerian::~Keplerian() +{ +} + + +/*! \brief Return a pointer to a new instance of a Keplerian orbit state representation type. + * + * This is used to request memory for a new instance of a Keplerian. It is necessary + * when attempting to get a pointer from the abstract data type OrbitStateRepresentation + * and the actual representation type isn't known. + * @return a pointer to a new allocation of memory for the Keplerian object. + */ +Keplerian* Keplerian::NewPointer() +{ + return new Keplerian(); +} + + +/*! \brief Return a pointer to a copy of the Keplerian orbit state representation instance. + * + * This is used to request memory for a copy of this instance of Keplerian. It is necessary + * when attempting to get a pointer from the abstract data type OrbitStateRepresentation + * and the actual representation type isn't known. + * @return a pointer to a copy of the Keplerian object. + */ +Keplerian* Keplerian::Clone() +{ + return new Keplerian(*this); +} + + +/*! \brief Create an initially empty Keplerian orbit state representation. */ +Keplerian::Keplerian() : m_OrbitalElements(NUM_KEPLERIAN_ELEMENTS) +{ +} + + +/*! Create a Keplerian orbit state representation from a vector of orbital elements. + * @param _Elements 6-element vector of Keplerian orbital elements [a, e, i, \f$\Omega\f$, \f$\omega\f$, \f$\nu\f$]. (km, -, rad, rad, rad, rad) + */ +Keplerian::Keplerian(const Vector& _Elements) +{ + SetState(_Elements); +} + + +/*! \brief Set the Keplerian representation by converting the position and velocity vectors in inertial coordinates. + * + * Required to match the OrbitStateRepresentation abstract class interface. + * \todo implement Keplerian conversion functions + * @param _Position 3-element vector of position components in inertial coordinates. (km) + * @param _Velocity 3-element vector of vector components in inertial coordinates. (km/s) + */ +void Keplerian::SetPositionVelocity(const Vector& _Position, const Vector& _Velocity) +{ + Vector K_Vector(3); K_Vector(VectorIndexBase+2) = 1; + Vector AngMomentum = crossP(_Position, _Velocity); + Vector LineNodes = crossP(K_Vector, AngMomentum); + double r = norm2(_Position); + double v = norm2(_Velocity); + double n = norm2(LineNodes); + Vector Eccentricity = 1/MU * (pow(v,2) - MU/r) * _Position - _Position.dot(_Velocity)*_Velocity; + m_OrbitalElements(ECCENTRICITY) = norm2(Eccentricity); + double xi = pow(v,2) / 2 - MU/r; + + // Semimajor Axis, a + m_OrbitalElements(SEMIMAJOR_AXIS) = -MU / (2 * xi); + + // Inclination, i + m_OrbitalElements(INCLINATION) = acos(AngMomentum(VectorIndexBase + 2) / norm2(AngMomentum)); + + // Longitude of the Ascending Node, Omega + m_OrbitalElements(LONG_ASC_NODE) = LineNodes(VectorIndexBase) / norm2(LineNodes); + if (LineNodes(VectorIndexBase+1) < 0) + m_OrbitalElements(LONG_ASC_NODE) = 2*PI - m_OrbitalElements(LONG_ASC_NODE); + + // Argument of perigee, omega + m_OrbitalElements(ARG_PERIGEE) = LineNodes.dot(Eccentricity) / (n * m_OrbitalElements(ECCENTRICITY)); + if (Eccentricity(VectorIndexBase+2) < 0) + m_OrbitalElements(ARG_PERIGEE) = 2*PI - m_OrbitalElements(ARG_PERIGEE); + + // True Anomaly, nu + m_OrbitalElements(TRUE_ANOMALY) = Eccentricity.dot(_Position) / (r * m_OrbitalElements(ECCENTRICITY)); + if (_Position.dot(_Velocity) < 0) + m_OrbitalElements(TRUE_ANOMALY) = 2*PI - m_OrbitalElements(TRUE_ANOMALY); + + // Special Cases + if(m_OrbitalElements(ECCENTRICITY) == 0) + { // Circular + m_OrbitalElements(ARG_PERIGEE) = 0; + if(m_OrbitalElements(INCLINATION) == 0) + { // Circular Equatorial - define True Longitude, lambda_true + m_OrbitalElements(LONG_ASC_NODE) = 0; + m_OrbitalElements(TRUE_ANOMALY) = _Position(VectorIndexBase) / r; + if(_Position(VectorIndexBase+1) < 0) + m_OrbitalElements(TRUE_ANOMALY) = 2*PI - m_OrbitalElements(TRUE_ANOMALY); + } + else + { // Circular Inclined - define Argument of Latitude, u + m_OrbitalElements(TRUE_ANOMALY) = LineNodes.dot(_Position)/(n * r); + if(_Position(VectorIndexBase+2) < 0) + m_OrbitalElements(TRUE_ANOMALY) = 2*PI - m_OrbitalElements(TRUE_ANOMALY); + } + } + else if(m_OrbitalElements(INCLINATION) == 0) + { // Elliptical Equitorial - define True Longitude of Periapsis, ~omega~ + m_OrbitalElements(LONG_ASC_NODE) = 0; + m_OrbitalElements(ARG_PERIGEE) = Eccentricity(VectorIndexBase) / m_OrbitalElements(ECCENTRICITY); + if (Eccentricity(VectorIndexBase+2) < 0) + m_OrbitalElements(ARG_PERIGEE) = 2*PI - m_OrbitalElements(ARG_PERIGEE); + } + return; +} + + +/*! \brief Set the Keplerian representation by converting the position and velocity vector given in inertial coordinates. + * + * required to match the OrbitStateRepresentation abstract class interface. + * \todo implement Keplerian conversion functions + * @param _Position 6-element vector of position and velocity components in inertial coordinates. (km, km/s) + */ +void Keplerian::SetPositionVelocity(const Vector& _PositionVelocity) +{ + Vector Pos(3); Pos(_) = _PositionVelocity(_(VectorIndexBase, VectorIndexBase+2)); + Vector Vel(3); Vel(_) = _PositionVelocity(_(VectorIndexBase+3, VectorIndexBase+5)); + + SetPositionVelocity(Pos, Vel); +} + + +/*! \brief Set the Keplerian representation by converting the position and velocity vectors. + * \todo implement Keplerian conversion functions + * @param _Position 3-element vector of position components. (km) + * @param _Velocity 3-element vector of vector components. (km/s) + * @param _TargetOrbFrame Reference frame that the vector components are in. + */ +void Keplerian::SetPositionVelocity(const Vector& _Position, const Vector& _Velocity, const OrbitFrame& _OrbFrame) +{ + // Convert the position and velocity vectors to inertial frame components + Vector Position = _OrbFrame.GetRotation2IJK() * _Position; + Vector Velocity = _OrbFrame.GetRotation2IJK() * _Velocity; + + // Call the inertial version of the SetPositionVelocity() + SetPositionVelocity(Position, Velocity); +} + + + /*! \brief Set the Keplerian representation by converting the position and velocity vector. + * \todo implement Keplerian conversion functions + * @param _Position 6-element vector of position and velocity components. (km, km/s) + * @param _TargetOrbFrame Reference frame that the vector components are in. + */ +void Keplerian::SetPositionVelocity(const Vector& _PositionVelocity, const OrbitFrame& _OrbFrame) +{ + Vector Pos(3); Pos(_) = _PositionVelocity(_(VectorIndexBase, VectorIndexBase+2)); + Vector Vel(3); Vel(_) = _PositionVelocity(_(VectorIndexBase+3, VectorIndexBase+5)); + + SetPositionVelocity(Pos, Vel, _OrbFrame); +} + + +/*! \brief Convert the Keplerian orbit representation to position and velocity vectors in the inertial frame. + * + * Required to match the OrbitStateRepresentation abstract class interface. + * @return 6-element vector of position and velocity vector components in the inertial reference frame. [km, km, km, km/s, km/s, km/s]^T + */ +Vector Keplerian::GetPositionVelocity() const +{ + Vector rv(6); + rv(VectorIndexBase + 0) = (GetSemiParameter() * cos(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly())); + rv(VectorIndexBase + 1) = (GetSemiParameter() * sin(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly())); + //rv(VectorIndexBase + 2) = 0; + rv(VectorIndexBase + 3) = -sqrt(MU/GetSemiParameter()) * sin(GetTrueAnomaly()); + rv(VectorIndexBase + 4) = sqrt(MU/GetSemiParameter()) * (GetEccentricity() + cos(GetTrueAnomaly())); + //rv(VectorIndexBase + 5) = 0; + return rv; +} + + +/*! \brief Convert the Keplerian orbit representation to position and velocity vectors in the specified frame. + * @param _TargetOrbFrame the desired reference frame to return the vector components in. + * @return 6-element vector of position and velocity vector components in the specified reference frame. [km, km, km, km/s, km/s, km/s]^T + */ +Vector Keplerian::GetPositionVelocity(const OrbitFrame& _TargetOrbFrame) const +{ + // Call the inertial version of GetPositionVelocity() + Vector rv = GetPositionVelocity(); + + // Convert from the inertial frame to the specified target frame + rv(_(VectorIndexBase, VectorIndexBase+2)) = _TargetOrbFrame.GetRotationFromIJK() * rv(_(VectorIndexBase, VectorIndexBase+2)); + rv(_(VectorIndexBase+3, VectorIndexBase+5)) = _TargetOrbFrame.GetRotationFromIJK() * rv(_(VectorIndexBase+3, VectorIndexBase+5)); + return rv; +} + + +/*! \brief Return by reference the converted the Keplerian orbit representation to position and velocity vectors in the inertial frame. + * + * required to match the OrbitStateRepresentation abstract class interface. + * @param _Position a Vector through which to return the 3-element position vector in inertial corrdinates. (km) + * @param _Velocity a Vector through which to return the 3-element velocity vector in inertial corrdinates. (km/s) + * @param _TargetOrbFrame the desired reference frame to return the vector components in. + */ +void Keplerian::GetPositionVelocity(Vector& _Position, Vector& _Velocity) const +{ + _Position(VectorIndexBase + 0) = (GetSemiParameter() * cos(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly())); + _Position(VectorIndexBase + 1) = (GetSemiParameter() * sin(GetTrueAnomaly())) / (1 + GetEccentricity() * cos(GetTrueAnomaly())); + _Position(VectorIndexBase + 2) = 0; + _Velocity(VectorIndexBase + 0) = -sqrt(MU/GetSemiParameter()) * sin(GetTrueAnomaly()); + _Velocity(VectorIndexBase + 1) = sqrt(MU/GetSemiParameter()) * (GetEccentricity() + cos(GetTrueAnomaly())); + _Velocity(VectorIndexBase + 2) = 0; + return; +} + + +/*! \brief Return by reference the converted Keplerian orbit representation to position and velocity vectors in the specified frame. + * @param _Position a Vector through which to return the 3-element position vector. (km) + * @param _Velocity a Vector through which to return the 3-element velocity vector. (km/s) + * @param _TargetOrbFrame the desired reference frame to return the vector components in. + */ +void Keplerian::GetPositionVelocity(Vector& _Position, Vector& _Velocity, const OrbitFrame& _TargetOrbFrame) const +{ + // Call the inertial version of GetPositionVelocity() + GetPositionVelocity(_Position, _Velocity); + + // Convert from the inertial frame to the specified target frame + _Position = _TargetOrbFrame.GetRotationFromIJK() * _Position; + _Velocity = _TargetOrbFrame.GetRotationFromIJK() * _Velocity; + return; +} + + +/*! \brief Solves Kepler's Equation in order to compute eccentric anomaly (E) from mean anomaly (M) and eccentricity (e). + * Adapted from Appendix A, Orbits, + * by Christopher D. Hall. Class notes for AOE 4140. + * Available at http://www.aoe.vt.edu/~chall/courses/aoe4140/ + * \todo Allow user to specify tolerance for numerical convergence. */ +double Keplerian::GetEccentricAnomalyFromMeanAnomaly(const double& _MeanAnomaly) +{ + + double tolerance = 1e-11; // sets convergence level + /*! \todo Allow user to specify tolerance for numerical convergence. */ + double _EccentricAnomaly; // returned value + double testEccAnomaly; // candidate EA, for convergence test + double eccentricity = m_OrbitalElements(ECCENTRICITY); + // from Keplerian private data member + + testEccAnomaly = _MeanAnomaly; + _EccentricAnomaly = testEccAnomaly - + ( testEccAnomaly - eccentricity*sin(testEccAnomaly) - _MeanAnomaly ) / + ( 1 - eccentricity*cos(testEccAnomaly) ); + + while ( fabs(_EccentricAnomaly-testEccAnomaly) > tolerance ) // iterate until _EA = testEA + { + testEccAnomaly = _EccentricAnomaly; + _EccentricAnomaly = testEccAnomaly - + ( testEccAnomaly - eccentricity*sin(testEccAnomaly) - _MeanAnomaly ) / + ( 1 - eccentricity*cos(testEccAnomaly) ); + } + + return _EccentricAnomaly; +} + + +/*! \brief Calculates true anomaly (\f$\nu\f$) from eccentric + * anomaly (E), semimajor axis (a), and eccentricity (e). + */ +/*! Adapted from Appendix A, Orbits, + * by Christopher D. Hall. Class notes for AOE 4140. + * Available at http://www.aoe.vt.edu/~chall/courses/aoe4140/ + */ +void Keplerian::GetTrueAnomalyFromEccentricAnomaly(const double& _EccentricAnomaly) +{ + + double cosTrueAnomaly; + double sinTrueAnomaly; + double semimajoraxis = m_OrbitalElements(SEMIMAJOR_AXIS); + double eccentricity = m_OrbitalElements(ECCENTRICITY); + + cosTrueAnomaly = ( eccentricity - cos(_EccentricAnomaly) ) / + ( eccentricity*cos(_EccentricAnomaly) - 1 ); + sinTrueAnomaly = ( ( semimajoraxis*sqrt(1 - eccentricity*eccentricity) ) / + ( semimajoraxis*(1 - eccentricity*cos(_EccentricAnomaly)) ) ) * + sin(_EccentricAnomaly); + + m_OrbitalElements(TRUE_ANOMALY) = atan2( sinTrueAnomaly, cosTrueAnomaly ); + if ( m_OrbitalElements(TRUE_ANOMALY) < 0 ); + { + m_OrbitalElements(TRUE_ANOMALY) = m_OrbitalElements(TRUE_ANOMALY) + 2*PI; + } + + return; +} + + +/*! \brief Parses a two line element set and updates orbital + * elements, returns a struct of additional information. + */ +/*! Adapted from Appendix A, Orbits, + * by Christopher D. Hall. Class notes for AOE 4140. + * Available at http://www.aoe.vt.edu/~chall/courses/aoe4140/ + * + * Sample TLEs: + * COSMOS 2278 + * 1 23087U 94023A 98011.59348139 .00000348 00000-0 21464-3 0 5260 + * 2 23087 71.0176 58.4285 0007185 172.8790 187.2435 14.12274429191907 + * + * NOAA 14 + * 1 23455U 94089A 97320.90946019 .00000140 00000-0 10191-3 0 2621 + * 2 23455 99.0090 272.6745 0008546 223.1686 136.8816 14.11711747148495 + * + * + * TLE Definition + * AAAAAAAAAAAAAAAAAAAAAAAA + * 1 NNNNNU NNNNNAAA NNNNN.NNNNNNNN +.NNNNNNNN +NNNNN-N +NNNNN-N N NNNNN + * 2 NNNNN NNN.NNNN NNN.NNNN NNNNNNN NNN.NNNN NNN.NNNN NN.NNNNNNNNNNNNNN + * Line 0 is a twenty-four character name (to be consistent with the + * name length in the NORAD SATCAT). + * Lines 1 and 2 are the standard Two-Line Orbital Element Set Format + * identical to that used by NORAD and NASA. + */ +tleStruct Keplerian::ReadTwoLineElementSet(const string& _TwoLineElementSet) +{ + + int finder = 0; // the start of each substring + int endlfinder; // the end of each substring + int finderLength; // the length of each substring + + string LineZero; // of the tle... + string LineOne; + string LineTwo; + + stringstream placeholder; // an aptly named translator + int exponent; // for \ddot{meanmotion} and bstar + +// Parse the TLE into three lines by finding endline markers ('\n')... + endlfinder = _TwoLineElementSet.find('\n',finder); // found one! + finderLength = endlfinder - finder; // "how long is it?" + LineZero = _TwoLineElementSet.substr(finder,finderLength); // ok, get it. + + finder = endlfinder + 1; // go to the next character + endlfinder = _TwoLineElementSet.find('\n',finder); // and repeat x2! + finderLength = endlfinder - finder; + LineOne = _TwoLineElementSet.substr(finder,finderLength); + + finder = endlfinder + 1; + endlfinder = _TwoLineElementSet.size(); + finderLength = endlfinder - finder; + LineTwo = _TwoLineElementSet.substr(finder,finderLength); + + /*! \todo Error checking for syntactically correct TLEs, including endlines, carriage returns. */ +// Done parsing the TLE into lines. + + +// Unpack Line Zero. + // Line 0 Column Description + // 01-24 Satellite SATCAT Name + m_tleData.satName = LineZero.substr(0,24); +// It's a short line! + +// Unpack Line One. + // Line 1 Column Description + // 01 Line Number of Element Data, not saved. + // 03-07 Satellite Number + finder = 2; // LineOne = [1 SatNum... + endlfinder = LineOne.find(' ',finder); // Look for the next space + finderLength = endlfinder - finder; // Just for readability + placeholder << LineOne.substr(finder,finderLength-1); // Pull string into streamstring + placeholder >> m_tleData.satNumber; // Push streamstring into _____ (in this case, an int) + // 08 Classification (U=Unclassified) + placeholder.clear(); // Still part of the first substring + placeholder << LineOne.substr(endlfinder-1,1); + placeholder >> m_tleData.satClassification; + // ah, whitespace. + // 10-11 International Designator (Last two digits of launch year) + finder = endlfinder + 1; + endlfinder = LineOne.find(' ',finder); + placeholder.clear(); + placeholder << LineOne.substr(finder,2); // gotta be 2 (ints) long + placeholder >> m_tleData.launchYear; + /*! \todo Include full year info logic as per the tle standard, + wherein 57-99 --> 19__ and 00-56 --> 20__. */ + // 12-14 International Designator (Launch number of the year) + placeholder.clear(); + placeholder << LineOne.substr(finder+2,3); // assuming 3 ints, as per the standard + placeholder >> m_tleData.launchNumber; + // 15-17 International Designator (Piece of the launch) + placeholder.clear(); + finderLength = endlfinder - finder; + placeholder << LineOne.substr(finder+5,finderLength-5); // should be 3 chars, but who knows? + placeholder >> m_tleData.launchPiece; + + // 19-20 Epoch Year (Last two digits of year) + finder = endlfinder + 1; + endlfinder = LineOne.find(' ',finder); + placeholder.clear(); + placeholder << LineOne.substr(finder,2); // gotta be 2 ints long + placeholder >> m_tleData.epochYear; + // 21-32 Epoch (Day of the year and fractional portion of the day) + placeholder.clear(); + finderLength = endlfinder - finder; + placeholder << LineOne.substr(finder+2,finderLength-2); // double until next whitespace. + placeholder >> m_tleData.epochDay; + + // 34-43 First Time Derivative of the Mean Motion + finder = endlfinder + 1; + endlfinder = LineOne.find(' ',finder); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineOne.substr(finder,finderLength); + placeholder >> m_tleData.meanmotion1stDeriv; + + // 45-52 Second Time Derivative of Mean Motion (leading decimal point assumed) + finder = endlfinder + 1; + endlfinder = LineOne.find_first_of("-+",finder+1); // +- starts the exponent + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineOne.substr(finder,finderLength); + placeholder >> m_tleData.meanmotion2ndDeriv; // so this is just the raw operand + finder = endlfinder; + endlfinder = LineOne.find(' ',finder); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineOne.substr(finder,finderLength); + placeholder >> exponent; // here's the exponent + m_tleData.meanmotion2ndDeriv *= pow(10.0,exponent); // this is op^exp + if ( LineOne[finder] == '+' || LineOne[finder] == '-' ) // now include the leading decimal point + m_tleData.meanmotion2ndDeriv /= pow(10.0,finderLength-1); + else + m_tleData.meanmotion2ndDeriv /= pow(10.0,finderLength); + + // 54-61 BSTAR drag term (leading decimal point assumed) + finder = endlfinder + 1; + endlfinder = LineOne.find_first_of("-+",finder+1); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineOne.substr(finder,finderLength); + placeholder >> m_tleData.bstarDrag; + finder = endlfinder; + endlfinder = LineOne.find(' ',finder); + placeholder.clear(); + placeholder << LineOne.substr(finder,finderLength); + placeholder >> exponent; + m_tleData.bstarDrag *= pow(10.0,exponent); + if ( LineOne[finder] == '+' || LineOne[finder] == '-' ) + m_tleData.bstarDrag /= pow(10.0,finderLength-1); + else + m_tleData.bstarDrag /= pow(10.0,finderLength); + + // 63 Ephemeris type + finder = endlfinder + 1; + endlfinder = LineOne.find(' ',finder); + finderLength = endlfinder - finder; // = 1 + placeholder.clear(); + placeholder << LineOne.substr(finder,finderLength); + placeholder >> m_tleData.ephemerisType; + + // 65-68 Element number + finder = endlfinder + 1; + endlfinder = LineOne.size()-1; // end of the line, minus 1 for checksum and 1 for \n + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineOne.substr(finder,finderLength); + placeholder >> m_tleData.elementNumber; + + // 69 Checksum (Modulo 10) + placeholder.clear(); + placeholder << LineOne.substr(endlfinder,1); // end of the line, less \n + placeholder >> m_tleData.checksumLine1; +// Done with LineOne. + +// Onto LineTwo! + // Line 2 Column Description + // 01 Line Number of Element Data, not saved + // 03-07 Satellite Number, not saved here (saved in Line 1) + // 09-16 Inclination [Degrees], in m_OrbitalElements [radians] + endlfinder = LineTwo.find(' ',2); // start looking for ' ' inside the satellite number + finder = endlfinder + 1; + endlfinder = LineTwo.find(' ',finder); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineTwo.substr(finder,finderLength); + placeholder >> m_OrbitalElements(INCLINATION); // Keplerian private data member + m_OrbitalElements(INCLINATION) *= PI/180.0; // consistent units are good squishy. + + // 18-25 Right Ascension of the Ascending Node [Degrees], in m_OrbitalElements [radians] + finder = endlfinder + 1; + endlfinder = LineTwo.find(' ',finder); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineTwo.substr(finder,finderLength); + placeholder >> m_OrbitalElements(LONG_ASC_NODE); + m_OrbitalElements(LONG_ASC_NODE) *= PI/180.0; + /*! \todo verify that RAAN = longitude of the ascending node. */ + + // 27-33 Eccentricity (leading decimal point assumed), in m_OrbitalElements + finder = endlfinder + 1; + endlfinder = LineTwo.find(' ',finder); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << "0." << LineTwo.substr(finder,finderLength); + placeholder >> m_OrbitalElements(ECCENTRICITY); + m_OrbitalElements(ECCENTRICITY) *= PI/180.0; + + // 35-42 Argument of Perigee [Degrees], in m_OrbitalElements [radians] + finder = endlfinder + 1; + endlfinder = LineTwo.find(' ',finder); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineTwo.substr(finder,finderLength); + placeholder >> m_OrbitalElements(ARG_PERIGEE); + m_OrbitalElements(ARG_PERIGEE) *= PI/180.0; + + // 44-51 Mean Anomaly [Degrees], in m_OrbitalElements [radians] + finder = endlfinder + 1; + endlfinder = LineTwo.find(' ',finder); + finderLength = endlfinder - finder; + placeholder.clear(); + placeholder << LineTwo.substr(finder,finderLength); + placeholder >> m_tleData.meanAnomaly; + m_tleData.meanAnomaly *= PI/180.0; + m_tleData.eccentricAnomaly = GetEccentricAnomalyFromMeanAnomaly(m_tleData.meanAnomaly); + + // 53-63 Mean Motion [Revs per day] + finder = endlfinder + 1; + endlfinder = LineTwo.size()-1; // last substring + placeholder.clear(); + placeholder << LineTwo.substr(finder,11); + placeholder >> m_tleData.meanMotion; + // Buy one mean motion, get a semi-major axis at no extra charge! + m_OrbitalElements(SEMIMAJOR_AXIS) = pow( (MU/pow(m_tleData.meanMotion,2)), (1.0/3.0) ); + // And now we can get true anomaly. + GetTrueAnomalyFromEccentricAnomaly(m_tleData.eccentricAnomaly); + + // 64-68 Revolution number at epoch [Revs] + placeholder.clear(); + placeholder << LineTwo.substr(finder+11,5); + placeholder >> m_tleData.revolutionNumber; + + // 69 Checksum (Modulo 10) + placeholder.clear(); + placeholder << LineTwo.substr(endlfinder,1); + placeholder >> m_tleData.checksumLine2; + + return m_tleData; +} + + +// end jls 030512 + + + + + + + + + + + + +/* ********* DEPRECATED FUNCTIONS ********* */ + + + +/*! \brief Set the vector of the representation's state vector. + * \warning Deprecated - Do Not Use - will be moved internally + */ +void Keplerian::SetState(const Vector& _Elements) +{ + m_OrbitalElements = _Elements; + return; +} + + +/*! \brief Return a vector of the representation's state vector. + * \warning Deprecated - Do Not Use - will be moved internally + */ +Vector Keplerian::GetState() const +{ + return m_OrbitalElements; +} + + +/*! \brief Return a vector by reference of the representation's state vector. + * \warning Deprecated - Do Not Use - will be moved internally + */ +void Keplerian::GetState(Vector& _Elements) const +{ + _Elements = m_OrbitalElements; + return; +} + + + + +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Keplerian.cpp,v $ +* Revision 1.10 2003/05/23 19:28:32 simpliciter +* Moved comments from header file, basic housekeeping. +* +* Revision 1.9 2003/05/20 20:49:05 simpliciter +* Added new functions for parsing TLEs: +* - GetEccentricAnomalyFromMeanAnomaly, +* - GetTrueAnomalyFromEccentricAnomaly, +* - ReadTwoLineElementSet. +* +* Revision 1.8 2003/05/15 21:00:44 nilspace +* Added SetPositionVelocity(Vector) function implementation. +* +* Revision 1.7 2003/05/05 20:46:37 nilspace +* Added inertial Get/SetPositionVelocity to conform to new OrbitStateRepresentation abstract class. +* +* Revision 1.6 2003/04/29 18:48:30 nilspace +* Added NewPointer and Clone functions to help in getting the correct memory allocation. +* +* Revision 1.5 2003/04/24 21:14:23 nilspace +* const'd all Get() functions. +* +* Revision 1.4 2003/04/24 20:10:46 nilspace +* const'd all Get() functions. +* +* Revision 1.3 2003/04/23 18:52:28 nilspace +* Updated to call correct OrbitFrame::GetRotation calls. +* Added temporary PI and MU values. +* Added K_Vector Values. +* +* Revision 1.2 2003/04/22 18:06:07 nilspace +* Added math for Matthew Berry. +* +* Revision 1.1 2003/04/08 22:47:35 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/orbit/orbitstaterep/Keplerian.h b/src/orbit/orbitstaterep/Keplerian.h new file mode 100644 index 0000000..e7f4ad8 --- /dev/null +++ b/src/orbit/orbitstaterep/Keplerian.h @@ -0,0 +1,217 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Keplerian.h +* \brief Implementation of the Keplerian Orbit State Representation Class. +* \author $Author: nilspace $ +* \version $Revision: 1.12 $ +* \date $Date: 2003/08/24 20:59:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* \todo include conversion functions +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_KEPLERIAN_H__ +#define __SSF_KEPLERIAN_H__ +#include "Matrix.h" +#include "OrbitStateRepresentation.h" +#include +#include +#include +using namespace std; + +#define MU 1 // not a good value for MU. +#ifndef PI +#include +#define PI M_PI +#endif +namespace O_SESSAME { + +/*! \ingroup OrbitStateRepresentation @{ */ +#define NUM_KEPLERIAN_ELEMENTS 6 /*!< number of elements in a Keplerian state representation */ +const int SEMIMAJOR_AXIS = VectorIndexBase + 0; /*!< position of the Semimajor axis, \f$a\f$, in the element vector */ +const int ECCENTRICITY = VectorIndexBase + 1; /*!< position of the eccentricity, \f$e\f$, in the element vector */ +const int INCLINATION = VectorIndexBase + 2; /*!< position of the inclination, \f$i\f$, in the element vector */ +const int LONG_ASC_NODE = VectorIndexBase + 3; /*!< position of the longitude of the ascending node, \f$\Omega\f$, in the element vector */ +const int ARG_PERIGEE = VectorIndexBase + 4; /*!< position of the argument of perigee, \f$\omega\f$, in the element vector */ +const int TRUE_ANOMALY = VectorIndexBase + 5; /*!< position of the true anomaly, \f$\nu\f$, in the element vector */ +/** @} */ + +typedef struct tleStruct { + string satName; /*!< Satellite Name, from Line Zero */ + int satNumber; /*!< Satellite Number, from Line One */ + char satClassification; /*!< Almost always "U"nclassified (L1) */ + int launchYear; /*!< Launched in... (L1) */ + int launchNumber; /*!< Which launch of that year... (L1) */ + string launchPiece; /*!< Which piece of that launch... (L1) */ + int epochYear; /*!< Epoch year for this TLE (L1) */ + double epochDay; /*!< Epoch day and time for this TLE (L1) */ + double meanmotion1stDeriv; /*!< \f$\dot{meanMotion}\f$ (L1) */ + double meanmotion2ndDeriv; /*!< \f$\ddot{meanMotion}\f$ (L1) */ + double bstarDrag; /*!< B* drag term (L1) */ + int ephemerisType; /*!< The type of ephemeris data (L1) */ + int elementNumber; /*!< The TLE # (L1) */ + int checksumLine1; /*!< Checksum for L1 */ + double meanAnomaly; /*!< The TLE reports Mean Anomaly (L2) */ + double eccentricAnomaly; /*!< We calculate Eccentric Anomaly */ + double meanMotion; /*!< We calculate Mean Motion */ + int revolutionNumber; /*!< How many orbits at epoch? (L2) */ + int checksumLine2; /*!< Checksum for L2 */ +}; + + + +/*! \brief Keplerian orbital element representation of the orbital position. + * \ingroup OrbitStateRepresentation + * + * The Keplerian class stores the orbital elements of an orbital position. + * + * \par Example: + * + */ +class Keplerian : public OrbitStateRepresentation +{ +public: + + virtual ~Keplerian(); + + virtual Keplerian* NewPointer(); + + virtual Keplerian* Clone(); + + Keplerian(); + + Keplerian(const Vector& _Elements); + + void SetPositionVelocity(const Vector& _Position, const Vector& _Velocity); + + void SetPositionVelocity(const Vector& _PositionVelocity); + + void SetPositionVelocity(const Vector& _Position, const Vector& _Velocity, const OrbitFrame& _OrbFrame); + + void SetPositionVelocity(const Vector& _PositionVelocity, const OrbitFrame& _OrbFrame); + + Vector GetPositionVelocity() const; + + Vector GetPositionVelocity(const OrbitFrame& _TargetOrbFrame) const; + + void GetPositionVelocity(Vector& _Position, Vector& _Velocity) const; + + void GetPositionVelocity(Vector& _Position, Vector& _Velocity, const OrbitFrame& _TargetOrbFrame) const; + + double GetEccentricAnomalyFromMeanAnomaly(const double& _MeanAnomaly); + + void GetTrueAnomalyFromEccentricAnomaly(const double& _EccentricAnomaly); + + tleStruct ReadTwoLineElementSet(const string& _TwoLineElementSet); + + + +/* ********* KEPLERIAN SPECIFIC FUNCTIONS ********* */ + +/*! @defgroup ElementAccessFunctions Element Access functions + * \ingroup OrbitStateRepresentation + * \brief Functions to access the specific elements of the Keplerian Orbital Elements. + * @{ + */ +/*! \brief Compute and return the Semiparameter \f$p\f$ of the orbit position. + * @return the semiparameter: \f$p = a * (1-e^{2})\f$. (km) + */ + inline double GetSemiParameter() const {return GetSemimajorAxis() * (1 - pow(GetEccentricity(),2));}; + +/*! \brief Return the Semimajor Axis \f$a\f$ of the orbit position. (km) */ + inline double GetSemimajorAxis() const {return m_OrbitalElements(SEMIMAJOR_AXIS);}; + +/*! \brief Return the Eccentricity \f$e\f$ of the orbit position. (-) */ + inline double GetEccentricity() const {return m_OrbitalElements(ECCENTRICITY);}; + +/*! \brief Return the Inclination \f$i\f$ of the orbit position. (-) */ + inline double GetInclination() const {return m_OrbitalElements(INCLINATION);}; + +/*! \brief Return the Longitude of the Ascending Node \f$\Omega\f$ of the orbit position. (rad) */ + inline double GetLongAscNode() const {return m_OrbitalElements(LONG_ASC_NODE);}; + +/*! \brief Return the Argument of Perigee \f$\omega\f$ of the orbit position. (rad) */ + inline double GetArgPerigee() const {return m_OrbitalElements(ARG_PERIGEE);}; + +/*! \brief Return the True Anomaly \f$\nu\f$ of the orbit position. (rad) */ + inline double GetTrueAnomaly() const {return m_OrbitalElements(TRUE_ANOMALY);}; + +/*! \brief Return the Mean orbital motion \f$n\f$ of the orbit position. (rad/s) */ + inline double GetMeanMotion() const {return sqrt(MU/pow(GetSemimajorAxis(),3));}; + +/*! @} */ + +/* ********* ********* ******** ********* ********* */ + + + + + +/* ********* DEPRECATED FUNCTIONS ********* */ + + virtual void SetState(const Vector& _Elements); + + virtual Vector GetState() const; + + virtual void GetState(Vector& _Elements) const; + +/* ********* ********** ********* ********* */ + + + +private: + /*! 6x1 vector of Keplerian orbital elements [a, e, i, \f$\Omega\f$, \f$\omega\f$, \f$\nu\f$] (km, -, rad, rad, rad, rad)*/ + Vector m_OrbitalElements; + + /*! All of the non-orbital element data that's inside of a TLE. */ + tleStruct m_tleData; +}; +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Keplerian.h,v $ +* Revision 1.12 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.11 2003/05/23 19:28:14 simpliciter +* Moved comments to implementation file, basic housekeeping. +* +* Revision 1.10 2003/05/20 20:49:42 simpliciter +* Added new functions for parsing TLEs: +* - GetEccentricAnomalyFromMeanAnomaly, +* - GetTrueAnomalyFromEccentricAnomaly, +* - ReadTwoLineElementSet. +* +* Revision 1.9 2003/05/13 18:47:56 nilspace +* Fixed comments for better formatting. +* +* Revision 1.8 2003/05/05 20:46:38 nilspace +* Added inertial Get/SetPositionVelocity to conform to new OrbitStateRepresentation abstract class. +* +* Revision 1.7 2003/05/02 16:16:46 nilspace +* Documented the API. +* +* Revision 1.6 2003/04/29 18:48:30 nilspace +* Added NewPointer and Clone functions to help in getting the correct memory allocation. +* +* Revision 1.5 2003/04/24 21:14:23 nilspace +* const'd all Get() functions. +* +* Revision 1.4 2003/04/24 20:10:47 nilspace +* const'd all Get() functions. +* +* Revision 1.3 2003/04/23 18:52:29 nilspace +* Updated to call correct OrbitFrame::GetRotation calls. +* Added temporary PI and MU values. +* Added K_Vector Values. +* +* Revision 1.2 2003/04/22 18:06:08 nilspace +* Added math for Matthew Berry. +* +* Revision 1.1 2003/04/08 22:47:35 nilspace +* Initial Submission. +* +******************************************************************************/ diff --git a/src/orbit/orbitstaterep/OrbitStateRepresentation.cpp b/src/orbit/orbitstaterep/OrbitStateRepresentation.cpp new file mode 100644 index 0000000..9055a85 --- /dev/null +++ b/src/orbit/orbitstaterep/OrbitStateRepresentation.cpp @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitStateRepresentation.cpp +* \brief Implementation of the Orbit State Representation Class. +* \author $Author: nilspace $ +* \version $Revision: 1.1 $ +* \date $Date: 2003/04/08 22:47:35 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "OrbitStateRepresentation.h" + + + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitStateRepresentation.cpp,v $ +* Revision 1.1 2003/04/08 22:47:35 nilspace +* Initial Submission. +* +* +******************************************************************************/ \ No newline at end of file diff --git a/src/orbit/orbitstaterep/OrbitStateRepresentation.h b/src/orbit/orbitstaterep/OrbitStateRepresentation.h new file mode 100644 index 0000000..0316315 --- /dev/null +++ b/src/orbit/orbitstaterep/OrbitStateRepresentation.h @@ -0,0 +1,152 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file OrbitStateRepresentation.h +* \brief Interface to the Orbit State Representation abstract Class. +* \author $Author: rsharo $ +* \version $Revision: 1.9 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_ORBIT_REPRESENTATION_H__ +#define __SSF_ORBIT_REPRESENTATION_H__ + +#include "Matrix.h" +#include "../orbitframes/OrbitFrame.h" +namespace O_SESSAME { + +/** @defgroup OrbitStateRepresentation Orbit State Represenations +* \ingroup OrbitToolkit +* The orbit state representations are the various ways of storing a trajectory of +* an object in 3-dimensional space. +* +*/ + +/*! \brief Abstract base type of the orbit state representation. +* \ingroup OrbitStateRepresentation +* +* \detail The OrbitStateRepresentation class provides an interface to the +* group of orbit state representations. This representation can be +* position & velocity, keplerian elements, canonical parameters, or any +* other representation of an orbit state. +* +* \par +* There can never be an actual instantiation of an OrbitStateRepresentation. +* This is an abstract data type (ADT) and just provides a required interface +* for the derived types. Don't try to use: OrbitStateRepresentation myOrbRep; +* Just use as a pointer to the derived types. +* +* \par Example: +* +* +*/ +class OrbitStateRepresentation +{ +public: + /*! \brief Set the orbit representation using position and velocity components. + * @param _Position 3-element vector of position components. (km) + * @param _Velocity 3-element vector of vector components. (km/s) + */ + virtual void SetPositionVelocity(const Vector &_Position, const Vector &_Velocity) = 0; + + /*! \brief Set the orbit representation using position and velocity components. + * @param _PositionVelocity 6-element vector of position \& velocity components. (km, km/s) + */ + virtual void SetPositionVelocity(const Vector &_PositionVelocity) = 0; + + /*! \brief Return the position and velocity vectors of the orbit state. + * @return 6-element vector of position and velocity vector components. [km, km, km, km/s, km/s, km/s]^T + */ + virtual Vector GetPositionVelocity() const = 0; + + /*! \brief Return the position and velocity vectors of the orbit state by reference (through the input parameters) + * @param _Position a Vector through which to return the 3-element position vector. (km) + * @param _Velocity a Vector through which to return the 3-element velocity vector. (km/s) + */ + virtual void GetPositionVelocity(Vector &_Position, Vector &_Velocity) const = 0; + + /*! \brief Return a pointer to a new instance of a derived orbit state representation type. + * + * \detail This is used to request memory for a new instance of a derived instance when the + * actual type of the derived object is unknown. By calling this function, the compiler + * links to the correct derived function to return a pointer and allocate memory of + * the correct type. + * \par Example: + * \code + * OrbitStateRepresentation* newOrbRep = oldOrbRep->NewPointer(); + * \endcode + * @return a pointer to a new allocation of memory for the appropriate representation. + */ + virtual OrbitStateRepresentation* NewPointer() = 0; + + /*! \brief Return a pointer to a copy of a derived instance orbit state representation type. + * + * \detail This is used to request memory for and copy of an instance of a derived representation when the + * actual type of the derived object is unknown. By calling this function, the compiler + * links to the correct derived function to return a pointer and allocate memory of + * the correct type and copy the data. + * \par Example: + \code + * OrbitStateRepresentation* copyOldOrbRep = oldOrbRep->Clone(); + \endcode + * @return a pointer to a copy of the appropriate representation. + */ + virtual OrbitStateRepresentation* Clone() = 0; + +// virtual void SetState(const Vector &_Elements1, const Vector &_Elements2) = 0; + /*! \brief Set the vector of the representation's state vector. + * \warning Depracted - Do Not Use - will be moved internally + */ + virtual void SetState(const Vector &_Elements) = 0; + + /*! \brief Return a vector of the representation's state vector. + * \warning Depracted - Do Not Use - will be moved internally + */ + virtual Vector GetState() const = 0; + +protected: + +private: + +}; +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: OrbitStateRepresentation.h,v $ +* Revision 1.9 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.8 2003/05/13 18:47:56 nilspace +* Fixed comments for better formatting. +* +* Revision 1.7 2003/05/05 20:47:38 nilspace +* Changed the Get/SetPositionVelocity functions to not require a OrbitFrame. +* +* Revision 1.6 2003/05/02 16:16:46 nilspace +* Documented the API. +* +* Revision 1.5 2003/04/29 18:48:31 nilspace +* Added NewPointer and Clone functions to help in getting the correct memory allocation. +* +* Revision 1.4 2003/04/24 21:14:23 nilspace +* const'd all Get() functions. +* +* Revision 1.3 2003/04/23 16:26:08 nilspace +* Updated directory structure & default parameters. +* +* Revision 1.2 2003/04/22 18:06:08 nilspace +* Added math for Matthew Berry. +* +* Revision 1.1 2003/04/08 22:47:35 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/orbit/orbitstaterep/PositionVelocity.cpp b/src/orbit/orbitstaterep/PositionVelocity.cpp new file mode 100644 index 0000000..05190ad --- /dev/null +++ b/src/orbit/orbitstaterep/PositionVelocity.cpp @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file PositionVelocity.cpp +* \brief Implementation of the Position/Velocity Coordinate Type Class. +* \author $Author: nilspace $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/04/29 18:48:31 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "PositionVelocity.h" +namespace O_SESSAME { +PositionVelocity::PositionVelocity() : m_Elements(NUM_POSVEL_ELEMENTS) +{ + +} + +PositionVelocity::~PositionVelocity() +{ +} + +PositionVelocity::PositionVelocity(const Vector &_Elements) +{ + SetState(_Elements); +} + +PositionVelocity::PositionVelocity(const Vector &_Position, const Vector &_Velocity) +{ + SetState(_Position, _Velocity); +} + +void PositionVelocity::SetState(const Vector &_Elements) +{ + m_Elements = _Elements; + return; +} +void PositionVelocity::SetState(const Vector &_Position, const Vector &_Velocity) +{ + m_Elements(_(VectorIndexBase, VectorIndexBase + _Position.getIndexBound()-1)) = _Position(_); + m_Elements(_(VectorIndexBase + _Position.getIndexBound(), VectorIndexBase+ _Position.getIndexBound()+ _Velocity.getIndexBound()-1)) = _Velocity(_); + return; +} +Vector PositionVelocity::GetState() const +{ + return m_Elements; +} + +void PositionVelocity::GetState(Vector &_Position, Vector &_Velocity) const +{ + int numPosElements = _Position.getIndexBound(); + int numVelElements = _Velocity.getIndexBound(); + _Position = m_Elements(_(VectorIndexBase,VectorIndexBase+numPosElements-1)); + _Velocity = m_Elements(_(VectorIndexBase+numPosElements, VectorIndexBase+numPosElements+numVelElements-1)); + return; +} + +void PositionVelocity::SetPositionVelocity(const Vector &_Position, const Vector &_Velocity) +{ + SetState(_Position, _Velocity); + return; +} + +PositionVelocity* PositionVelocity::NewPointer() +{ + return new PositionVelocity(); +} + +PositionVelocity* PositionVelocity::Clone() +{ + return new PositionVelocity(*this); +} + +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: PositionVelocity.cpp,v $ +* Revision 1.4 2003/04/29 18:48:31 nilspace +* Added NewPointer and Clone functions to help in getting the correct memory allocation. +* +* Revision 1.3 2003/04/24 21:14:24 nilspace +* const'd all Get() functions. +* +* Revision 1.2 2003/04/24 20:19:30 nilspace +* const'd all Get() functions. +* +* Revision 1.1 2003/04/08 22:47:35 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/orbit/orbitstaterep/PositionVelocity.h b/src/orbit/orbitstaterep/PositionVelocity.h new file mode 100644 index 0000000..496cb86 --- /dev/null +++ b/src/orbit/orbitstaterep/PositionVelocity.h @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file PositionVelocity.h +* \brief Implementation of the Position/Velocity Coordinate Type Class. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/05/13 18:47:56 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \warning OrbitFrame conversions not included yet +* \todo include conversion functions +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_POSITIONVELOCITY_H__ +#define __SSF_POSITIONVELOCITY_H__ +#include "Matrix.h" +#include "OrbitStateRepresentation.h" + +namespace O_SESSAME { +/*! \ingroup OrbitStateRepresentation @{ */ +#define NUM_POSVEL_ELEMENTS 6 /*!< Number of elements in the Position/Velocity elements vector */ +/** @} */ + +/*! \brief Position & Velocity representation of the orbital position. +* \ingroup OrbitStateRepresentation +* +* \detail The PositionVelocity class stores the position and velocity components of an orbital position. +* This should be used in an OrbitState object to also store the appropriate reference frame. +* +* \par Example: +* +*/ +class PositionVelocity : public OrbitStateRepresentation +{ +public: + /*! \brief Create an initially empty PositionVelocity orbit state representation. */ + PositionVelocity(); + /*! \brief Create a PositionVelocity orbit state representation from a vector of the position & velocity elements. + * @param _State 6-element vector of the position and velocity components. (km, km/s) + */ + PositionVelocity(const Vector &_State); + /*! \brief Create a PositionVelocity orbit state representation from the position & velocity vectors. + * @param _Position 3-element vector of the position components. (km) + * @param _Velocity 3-element vector of the velocity components. (km/s) + */ + PositionVelocity(const Vector &_Position, const Vector &_Velocity); + + /*! \brief Default Deconstructor */ + virtual ~PositionVelocity(); + + /*! \brief Set the PositionVelocity representation directly from the position and velocity vectors. + * @param _Position 3-element vector of position components. (km) + * @param _Velocity 3-element vector of vector components. (km/s) + * @param _TargetOrbFrame Reference frame that the vector components are in. + */ + void SetPositionVelocity(const Vector &_Position, const Vector &_Velocity); + /*! \brief Set the PositionVelocity representation by converting the position and velocity vector. + * @param _Position 6-element vector of position and velocity components. (km, km/s) + * @param _TargetOrbFrame Reference frame that the vector components are in. + */ + void SetPositionVelocity(const Vector &_PositionVelocity) {SetState(_PositionVelocity);}; + + /*! \brief Return the stored position and velocity vector. + * @return 6-element vector of position and velocity vector components. [km, km, km, km/s, km/s, km/s]^T + */ + Vector GetPositionVelocity() const {return GetState();}; + + /*! \brief Return the stored position and velocity vectors by reference. + * @param _Position a Vector through which to return the 3-element position vector. (km) + * @param _Velocity a Vector through which to return the 3-element velocity vector. (km/s) + */ + void GetPositionVelocity(Vector &_Position, Vector &_Velocity) const {GetState(_Position, _Velocity); return;}; + + /*! \brief Return a pointer to a new instance of a PositionVelocity orbit state representation type. + * + * \detail This is used to request memory for a new instance of a PositionVelocity. It is necessary + * when attempting to get a pointer from the abstract data type OrbitStateRepresentation + * and the actual representation type isn't known. + * @return a pointer to a new allocation of memory for the PositionVelocity object. + */ + virtual PositionVelocity* NewPointer(); + /*! \brief Return a pointer to a copy of the PositionVelocity orbit state representation instance. + * + * \detail This is used to request memory for a copy of this instance of PositionVelocity. It is necessary + * when attempting to get a pointer from the abstract data type OrbitStateRepresentation + * and the actual representation type isn't known. + * @return a pointer to a copy of the PositionVelocity object. + */ + virtual PositionVelocity* Clone(); + + + virtual void SetState(const Vector &_State); + virtual void SetState(const Vector &_Position, const Vector &_Velocity); + virtual Vector GetState() const; + virtual void GetState(Vector &_Position, Vector &_Velocity) const; + +private: + /*! 6x1 vector of position and velocity vector components (km, km/s) */ + Vector m_Elements; +}; +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: PositionVelocity.h,v $ +* Revision 1.7 2003/05/13 18:47:56 nilspace +* Fixed comments for better formatting. +* +* Revision 1.6 2003/05/02 16:16:47 nilspace +* Documented the API. +* +* Revision 1.5 2003/04/29 18:48:31 nilspace +* Added NewPointer and Clone functions to help in getting the correct memory allocation. +* +* Revision 1.4 2003/04/24 20:19:31 nilspace +* const'd all Get() functions. +* +* Revision 1.3 2003/04/23 18:52:29 nilspace +* Updated to call correct OrbitFrame::GetRotation calls. +* Added temporary PI and MU values. +* Added K_Vector Values. +* +* Revision 1.2 2003/04/22 18:06:08 nilspace +* Added math for Matthew Berry. +* +* Revision 1.1 2003/04/08 22:47:35 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/rotation/CVS/Entries b/src/rotation/CVS/Entries new file mode 100644 index 0000000..615ed9b --- /dev/null +++ b/src/rotation/CVS/Entries @@ -0,0 +1,5 @@ +/Jamfile/1.3/Mon Dec 8 14:48:27 2003// +/Rotation.cpp/1.24/Sat Oct 18 21:37:28 2003// +/Rotation.h/1.19/Sat Oct 18 21:37:28 2003// +/rotation.pro/1.7/Sat Oct 18 21:37:28 2003// +D diff --git a/src/rotation/CVS/Repository b/src/rotation/CVS/Repository new file mode 100644 index 0000000..b24ff9e --- /dev/null +++ b/src/rotation/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/rotation diff --git a/src/rotation/CVS/Root b/src/rotation/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/rotation/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/rotation/Jamfile b/src/rotation/Jamfile new file mode 100644 index 0000000..981c09b --- /dev/null +++ b/src/rotation/Jamfile @@ -0,0 +1,31 @@ +########################################### +# Rotation Jamfile +# +# $Author: simpliciter $ +# $Revision: 1.3 $ +# $Date: 2003/12/08 14:48:27 $ +########################################### + +SubDir OPENSESSAME_ROOT src rotation ; + +Objects Rotation.cpp ; +ObjectHdrs Rotation.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)rotation : Rotation.o ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)rotation$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : Rotation.h ; + + + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.3 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# ******************************************************************************/ + + + diff --git a/src/rotation/Rotation.cpp b/src/rotation/Rotation.cpp new file mode 100755 index 0000000..2dbfd9d --- /dev/null +++ b/src/rotation/Rotation.cpp @@ -0,0 +1,1505 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Rotation.cpp +* \brief Implementation of Rotation Namespace Objects. +* \brief Provides a set of functions to use Rotation matrices +* and their various representations. +* \author $Author: rsharo $ +* \version $Revision: 1.24 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \warning Testing not complete +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Rotation.h" + +namespace O_SESSAME { +/*! \brief Default Constructor. + * \brief Create a Rotation with no offset. + */ +Rotation::Rotation() : m_RotationSense(RIGHT_HAND) { } + +/*! \brief Default Destructor. + */ +Rotation::~Rotation() { } + +/*! \brief Create a Rotation from a direction cosine matrix. + * @param _inMatrix 3x3 matrix of Direction Cosine Matrix (DCM) values. + */ +Rotation::Rotation(const Matrix& _inMatrix) { Set(_inMatrix); } + +/*! \brief Create a Rotation from a direction cosine matrix. + * @param _DCM instance of Direction Cosine Matrix (DCM) class. + */ +Rotation::Rotation(const DirectionCosineMatrix& _Matrix) { Set(_Matrix); } + +/*! \brief Create a Rotation from an euler angle sequence. + * @param _Angles 3x1 matrix of euler angles. + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +Rotation::Rotation(const Vector& _Angles, const int& _Sequence) { Set(_Angles, _Sequence); } + +/*! \brief Create a Rotation from an euler angle sequence. + * @param _Angle1 first angles in Euler angle set. [rad] + * @param _Angle2 second angles in Euler angle set. [rad] + * @param _Angle3 third angles in Euler angle set. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +Rotation::Rotation(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence) { Set(_Angle1, _Angle2, _Angle3, _Sequence); } + +/*! \brief Create a Rotation from a given euler axis and angle. + * @param Axis 3x1 Euler Axis + * @param Angle Angle rotation about axis [rad]. + */ +Rotation::Rotation(const Vector& _Axis, const Angle& _Angle) { Set(_Axis, _Angle); } + +/*! \brief Create a Rotation from a given set of Modified Rodriguez Parameters. + * @param _MRP 3x1 MRP vector to be represented. + */ +Rotation::Rotation(const ModifiedRodriguezParameters& _MRP) { Set(_MRP); } + +/*! \brief Create a Rotation from a given quaternion. + * @param _quat 4x1 quaternion to be represented. + */ +Rotation::Rotation(const Quaternion& _quat) { Set(_quat); } + +/*! \brief Set the Rotation from a converted DCM. + * @param _inMatrix 3x3 matrix of Direction Cosine Matrix (DCM) values. + */ +void Rotation::Set(const Matrix& _inMatrix) +{/*! \todo Add testing for other types of matrix inputs */ + if((_inMatrix[MatrixRowsIndex].getIndexCount() == 3) && (_inMatrix[MatrixColsIndex].getIndexCount() == 3)) + { + m_quaternion.Set(DirectionCosineMatrix(_inMatrix)); + } + if((_inMatrix[MatrixRowsIndex].getIndexCount() == QUATERNION_SIZE) && (_inMatrix[MatrixColsIndex].getIndexCount() == 1)) + { +// m_quaternion.Set(_inMatrix(_,MatrixIndexBase)); + } + return; +} + + /*! \brief Set the Rotation from a converted DCM. + * @param _DCM 3x3 matrix of Direction Cosine Matrix (DCM) values. + */ +void Rotation::Set(const DirectionCosineMatrix& _DCM) +{ + m_quaternion.Set(_DCM); + return; +} + + /*! \brief Set the Rotation from an euler angle sequence. + * @param _Angles 3x1 matrix of euler angles. + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +void Rotation::Set(const Vector& _Angles, const int& _Sequence) +{ + m_quaternion.Set(_Angles, _Sequence); + return; +} + + /*! \brief Create a Rotation from an euler angle sequence. + * @param _Angle1 first angles in Euler angle set. [rad] + * @param _Angle2 second angles in Euler angle set. [rad] + * @param _Angle3 third angles in Euler angle set. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +void Rotation::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence) +{ + m_quaternion.Set(_Angle1, _Angle2, _Angle3, _Sequence); + return; +} + + /*! \brief Set the Rotation from a converted Euler Axis and Angle set. + * @param _Axis 3x1 Euler Axis. + * @param _Angle Angle rotation about axis [rad]. + */ +void Rotation::Set(const Vector& _Axis, const Angle& _Angle) +{ + m_quaternion.Set(_Axis, _Angle); + return; +} + + /*! \brief Set the Rotation from a converted vector of MRP. + * @param _MRP 3x1 vector of Modified Rodriguez Parameters to set the Rotation. + */ +void Rotation::Set(const ModifiedRodriguezParameters& _MRP) +{ + m_quaternion.Set(_MRP); + return; +} + + /*! \brief Set the Rotation from a converted quaternion. + * @param _quat 4x1 quaternion to set the Rotation. + */ +void Rotation::Set(const Quaternion& _quat) +{ + m_quaternion(1) = _quat(1); + m_quaternion(2) = _quat(2); + m_quaternion(3) = _quat(3); + m_quaternion(4) = _quat(4); + return; +} + +// Inspectors + /*! \brief Return the Direction Cosine Matrix (DCM) form of the attitude transformation. + * @return 3x3 Direction Cosine Matrix (DCM). + */ +DirectionCosineMatrix Rotation::GetDCM() const +{ + return DirectionCosineMatrix(m_quaternion); +} + + /*! \brief Return the Euler angles from the rotation representation. + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + * @return _Angles 3x1 matrix of euler angles. + */ +Vector Rotation::GetEulerAngles(const int& _Sequence) const +{ + return m_quaternion.GetEulerAngles(_Sequence); +} + + /*! \brief Return the Euler Axis and Angle form of the attitude transformation. + * @return 4-element vector of the Euler Axis and Angle [EulerAxis; EulerAngle]. + */ +Vector Rotation::GetEulerAxisAngle() const +{ + return m_quaternion.GetEulerAxisAngle(); +} + + /*! \brief Return the Euler Axis and Angle form of the attitude transformation. + * @param _EulerAxis 3x1 Euler Axis to be returned. + * @param _EulerAngle Euler angle of rotation [rad]. + */ +Vector Rotation::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const +{ + return m_quaternion.GetEulerAxisAngle(_EulerAxis, _EulerAngle); +} + + /*! \brief Return the Modified Rodriguez Parameters vector form of the attitude transformation. + * @return 3x1 MRP vector. + */ +ModifiedRodriguezParameters Rotation::GetMRP() const +{ + return ModifiedRodriguezParameters(m_quaternion); +} + + /*! \brief Return the quaternion form of the attitude transformation. + * @return 4x1 quaternion. + */ +Quaternion Rotation::GetQuaternion() const +{ + return m_quaternion; +} + + /*! \brief Return the rotation based on the specified parameterization. + * \todo completely document various rotation return types + * @param _type rotation parameterization type to return the rotation representation in. + * @param _Sequence for Euler Angle sets, specify the desired rotation sequence. + * @return the rotation represented by the specified rotation. + */ +Vector Rotation::GetRotation(const RotationType& _type, const int& _Sequence) const +{ + if(_type == DCM_Type) + { + Matrix tempMatrix = GetDCM(); + Vector tempVector(DCM_SIZE * DCM_SIZE); + // convert the 3x3 matrix into a 9x1 vector, by rows. + for (int ii = VectorIndexBase; ii < DCM_SIZE + VectorIndexBase; ++ii) + { + tempVector(_(VectorIndexBase + DCM_SIZE*(ii-VectorIndexBase),VectorIndexBase + DCM_SIZE*ii-1)) = ~tempMatrix(ii, _); + } + return tempVector; + } + else if(_type == EulerAngle_Type) + { + return GetEulerAngles(_Sequence); + } + else if(_type == EulerAxisAngle_Type) + { + return GetEulerAxisAngle(); + } + else if(_type == MRP_Type) + { + return (Vector)GetMRP(); + } + else if(_type == Quaternion_Type) + { + return (Vector)GetQuaternion(); + } + + // When in doubt, return the quaternion. + return (Vector)GetQuaternion(); +} + + /*! \brief Multiply the rotation matrices together to determine the successive rotation. + * @return the successive rotation representation. + */ +Rotation Rotation::operator* (const Rotation& _rot2) const +{ + return Rotation((*this).GetDCM() * _rot2.GetDCM()); +} + /*! \brief Multiply the rotation by the Vector for a rotation. + * @return 3x1 Rotated vector. + */ +Vector Rotation::operator* (const Vector& _vec2) const +{ + return ((*this).GetDCM() * _vec2); +} + + /*! \brief Take the inverse of the rotation matrix. + * @return 3x3 Direction Cosine Matrix (DCM). + */ +Rotation Rotation::operator~ () const +{ + Rotation rotOut(~((*this).GetDCM())); + return rotOut; +} + /*! \brief Determine the successive rotation from the summation of two rotations. + * @param _rot2 Rotation to be summed with. + */ +Rotation Rotation::operator+ (const Rotation& _rot2) const +{ + Rotation rotOut(this->operator*(_rot2)); + return rotOut; +} + /*! \brief Determine the relative rotation from the difference of two rotations. + * \f$R^{31} = R^{32} * R^{21} \Rightarrow R^{32} = R^{31} - R^{21} = R^{32} * R^{21}^{T}/f$ + * @param _rot2 Rotation to be differenced with. + * @return rotation of difference between given rotations. + */ +Rotation Rotation::operator- (const Rotation& _rot2) const +{ + Rotation rotOut(this->operator*(~_rot2)); + return rotOut; +} +////////////////////////////////////////////////////////////////////////// +// DirectionCosineMatrix Class + /*! \brief Create a DCM equal to the identity matrix [1,0,0;0,1,0;0,0,1]. + * @return 3x3 Direction Cosine Matrix equal to the identity matrix. + */ +DirectionCosineMatrix::DirectionCosineMatrix():Matrix(DCM_SIZE, DCM_SIZE) +{ + (*this) = eye(DCM_SIZE); +} + /*! \brief Create a copy of a DCM from an existing DCM. + * @param _DCM 3x3 Direction Cosine Matrix to be copied. + */ +DirectionCosineMatrix::DirectionCosineMatrix(const DirectionCosineMatrix& _DCM):Matrix(DCM_SIZE, DCM_SIZE) +{ + Set(_DCM); +} + /*! \brief Create a copy of a DCM from an existing matrix of DCM values. + * @param _DCM 3x3 matrix of DCM values to be copied. + */ +DirectionCosineMatrix::DirectionCosineMatrix(const Matrix& _DCM):Matrix(DCM_SIZE, DCM_SIZE) +{ + Set(_DCM); +} + + /*! \brief Create a Direction Cosine Matrix (DCM) from Euler Angles. + * @param _EulerAngles 3x1 matrix of Euler Angles. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +DirectionCosineMatrix::DirectionCosineMatrix(const Vector& _EulerAngles, const int& _Sequence):Matrix(DCM_SIZE, DCM_SIZE) +{ + Set(_EulerAngles, _Sequence); +} + + /*! \brief Create a Direction Cosine Matrix (DCM) from Euler Angles. + * @param _Angle1 first angles in Euler angle set. [rad] + * @param _Angle2 second angles in Euler angle set. [rad] + * @param _Angle3 third angles in Euler angle set. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +DirectionCosineMatrix::DirectionCosineMatrix(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence):Matrix(DCM_SIZE, DCM_SIZE) +{ + Set(_Angle1, _Angle2, _Angle3, _Sequence); +} + + /*! \brief Create a Direction Cosine Matrix (DCM) from an Euler Axis and rotation. + * @param _EulerAxis 3x1 Euler Axis vector (\f$\hat{e}\f$). + * @param _EulerAngle Angle rotation about axis (\f$\Phi\f$)[rad]. + */ +DirectionCosineMatrix::DirectionCosineMatrix(const Vector& _EulerAxis, const Angle& _EulerAngle):Matrix(DCM_SIZE, DCM_SIZE) +{ + Set(_EulerAxis, _EulerAngle); +} + + /*! \brief Create a Direction Cosine Matrix (DCM) from a vector of Modified Rodriguez Parameters (MRP). + * @param _MRP 3x1 MRP to be converted. + */ +DirectionCosineMatrix::DirectionCosineMatrix(const ModifiedRodriguezParameters& _MRP):Matrix(DCM_SIZE, DCM_SIZE) +{ + Set(_MRP); +} + /*! \brief Create a Direction Cosine Matrix (DCM) from a quaternion. + * @param _quat 4x1 quaternion to be converted. + * @return 3x3 Direction Cosine Matrix. + */ +DirectionCosineMatrix::DirectionCosineMatrix(const Quaternion& _quat):Matrix(DCM_SIZE, DCM_SIZE) +{ + Set(_quat); +} + /*! \brief Default deconstructor. + */ +DirectionCosineMatrix::~DirectionCosineMatrix() +{ +} + + /*! \brief Set a DCM to a copy of another DCM. + * @param _DCM 3x3 DCM to be copied. + */ +void DirectionCosineMatrix::Set(const DirectionCosineMatrix& _DCM) +{ + for (int ii = MatrixIndexBase; ii <= _DCM[MatrixRowsIndex].getIndexBound(); ++ii) + for (int jj = MatrixIndexBase; jj <= _DCM[MatrixColsIndex].getIndexBound(); ++jj) + (*this)(ii,jj) = _DCM(ii,jj); + Normalize(); + return; +} + + /*! \brief Set a DCM to a copy of an matrix that is a DCM. + * @param _DCM 3x3 Matrix of DCM values to be copied. + */ +void DirectionCosineMatrix::Set(const Matrix& _DCM) +{ + for (int ii = MatrixIndexBase; ii <= _DCM[MatrixRowsIndex].getIndexBound(); ++ii) + for (int jj = MatrixIndexBase; jj <= _DCM[MatrixColsIndex].getIndexBound(); ++jj) + (*this)(ii,jj) = _DCM(ii,jj); + Normalize(); + return; +} + + /*! \brief Set the DCM to the transformation of set of Euler Angles. + * @param _EulerAngles 3x1 matrix of Euler Angles. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +void DirectionCosineMatrix::Set(const Vector& _EulerAngles, const int& _Sequence) +{ + Set(_EulerAngles(VectorIndexBase+0), _EulerAngles(VectorIndexBase+1), _EulerAngles(VectorIndexBase+2), _Sequence); + return; +} + + /*! \brief Set the DCM to the transformation of set of Euler Angles. + * @param _Angle1 first angles in Euler angle set. [rad] + * @param _Angle2 second angles in Euler angle set. [rad] + * @param _Angle3 third angles in Euler angle set. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +void DirectionCosineMatrix::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence) +{ + switch(_Sequence) + { + case 121: (*this) = R1(_Angle3) * R2(_Angle2) * R1(_Angle1); break; + case 131: (*this) = R1(_Angle3) * R3(_Angle2) * R1(_Angle1); break; + case 132: (*this) = R2(_Angle3) * R3(_Angle2) * R1(_Angle1); break; + case 123: (*this) = R3(_Angle3) * R2(_Angle2) * R1(_Angle1); break; + case 212: (*this) = R2(_Angle3) * R1(_Angle2) * R2(_Angle1); break; + case 321: (*this) = R1(_Angle3) * R2(_Angle2) * R3(_Angle1); break; + case 232: (*this) = R2(_Angle3) * R3(_Angle2) * R2(_Angle1); break; + case 231: (*this) = R1(_Angle3) * R3(_Angle2) * R2(_Angle1); break; + case 213: (*this) = R3(_Angle3) * R1(_Angle2) * R2(_Angle1); break; + case 313: (*this) = R3(_Angle3) * R1(_Angle2) * R3(_Angle1); break; + case 323: (*this) = R3(_Angle3) * R2(_Angle2) * R3(_Angle1); break; + case 312: (*this) = R2(_Angle3) * R1(_Angle2) * R3(_Angle1); break; + default: (*this) = eye(DCM_SIZE); + } + Normalize(); + return; +} + +/*! \brief Set the DCM to the transformation of an Euler Axis and Angle. + * @param _EulerAxis 3x1 Euler Axis vector (\f$\hat{e}\f$). + * @param _EulerAngle Angle rotation about axis (\f$\Phi\f$)[rad]. + * + * \par Equation: (Ref Wertz, pg. 413) + * \f[ + * \bf{R} + * = + * \begin{bmatrix} + * e^{2}_1 \Phi + \cos{\phi} & e_1 e_2 \Phi + e_3\sin{\phi} & e_1 e_3 \Phi - e_2\sin{\phi}\\ + * e_2 e_1 \Phi - e_3\sin{\phi} & e^{2}_2 \Phi + \cos{\phi} & e_2 e_3 \Phi + e_1\sin{\phi}\\ + * e_3 e_1 \Phi + e_2\sin{\phi} & e_3 e_2 \Phi - e_1\sin{\phi} & e^{2}_3 \Phi + \cos{\phi} + * \end{bmatrix} + * \f] + * where \f$\Phi= 1 - \cos{\phi}\f$ (Ref Hughes p.12) + */ +void DirectionCosineMatrix::Set(const Vector& _EulerAxis, const Angle& _EulerAngle) +{ + // Calculations done for each element to increase speed + double Phi = 1 - cos(_EulerAngle); + double e1 = _EulerAxis(VectorIndexBase+0); + double e2 = _EulerAxis(VectorIndexBase+1); + double e3 = _EulerAxis(VectorIndexBase+2); + double cosPhi = cos(_EulerAngle); + double sinPhi = sin(_EulerAngle); + + // Column 1 + (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = e1 * e1 * Phi + cosPhi; + (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = e2 * e1 * Phi - e3 * sinPhi; + (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = e3 * e1 * Phi + e2 * sinPhi; + + // Column 2 + (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = e1 * e2 * Phi + e3 * sinPhi; + (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = e2 * e2 * Phi + cosPhi; + (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = e3 * e2 * Phi - e1 * sinPhi; + + // Column 3 + (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = e1 * e3 * Phi - e2 * sinPhi; + (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = e2 * e3 * Phi + e1 * sinPhi; + (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = e3 * e3 * Phi + cosPhi; + Normalize(); + return; +} + +/*! \brief Set the DCM to the transformation of Modified Rodriguez Paramaters (MRP). + * @param _MRP 3x1 matrix of Modified Rodriguez Parameters (MRP). + * \par Equation: + * \f[ + * \left[\bf{R}\left(\bf{\sigma}\right)\right] + * = + * \frac{1}{\left(1+\sigma^2\right)^2} + * \begin{bmatrix} + * 4\left(\sigma^{2}_1-\sigma^{2}_2-\sigma^{2}_3\right)+\Sigma^2 & 8\sigma_1\sigma_2+4\sigma_3\Sigma & 8\sigma_1\sigma_3-4\sigma_2\Sigma\\ + * 8\sigma_2\sigma_1-4\sigma_3\Sigma & 4\left(-\sigma^{2}_1+\sigma^{2}_2-\sigma^{2}_3\right)+\Sigma^2 & 8\sigma_2\sigma_3+4\sigma_1\Sigma + * 8\sigma_3\sigma_1+4\sigma_2\Sigma & 8\sigma_3\sigma_2-4\sigma_1\Sigma & 4\left(-\sigma^{2}_1-\sigma^{2}_2+\sigma^{2}_3\right)+\Sigma^2 + * \end{bmatrix} + * \f] + * where \f$\Sigma=1-\bf{\sigma}^T\bf{\sigma}\f$ + */ +void DirectionCosineMatrix::Set(const ModifiedRodriguezParameters& _MRP) +{ + // Calculations done for each element to increase speed + Matrix tempMatrix = (~(_MRP) * _MRP); + double Sigma = 1 - tempMatrix(MatrixIndexBase,MatrixIndexBase); + double sigma1 = _MRP(VectorIndexBase+0); + double sigma2 = _MRP(VectorIndexBase+1); + double sigma3 = _MRP(VectorIndexBase+2); + + // Column 1 + (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 4*(sigma1*sigma1 - sigma2*sigma2 - sigma3*sigma3) + Sigma*Sigma; + (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = 8*sigma2*sigma1 - 4*sigma3*Sigma; + (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = 8*sigma3*sigma1 + 4*sigma2*Sigma; + + // Column 2 + (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = 8*sigma1*sigma2 + 4*sigma3*Sigma; + (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = 4*(-sigma1*sigma1 + sigma2*sigma2 - sigma3*sigma3) + Sigma*Sigma; + (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = 8*sigma3*sigma2 - 4*sigma1*Sigma; + + // Column 3 + (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = 8*sigma1*sigma3 - 4*sigma2 * Sigma; + (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = 8*sigma2*sigma3 + 4*sigma1*Sigma; + (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = 4*(-sigma1*sigma1 - sigma2*sigma2 + sigma3*sigma3) + Sigma*Sigma; + + // Multiplying factor + (*this) /= pow(1 + tempMatrix(MatrixIndexBase,MatrixIndexBase), 2); + Normalize(); + return; +} + +/*! \brief Set a DCM to the transformation of a quaternion. + * \par Equation: + * @param _qIn 4x1 quaternion to be converted. + * \par Equation: (Ref Wertz, pg. 414) + * \f[ + * \left[\bf{R}\left(\bf{\bar{q}}\right)\right] + * = + * \begin{bmatrix} + * 1-2(q_{2}^{2}+q_{3}^{2}) & 2\left(q_1 q_2 + q_4 q_3\right) & 2\left(q_1 q_3 - q_4 q_2\right)\\ + * 2\left(q_1 q_2 - q_4 q_3\right) & 1-2(q_{1}^{2}+q_{3}^{2}) & 2\left(q_2 q_3 + q_4 q_1\right)\\ + * 2\left(q_1 q_3 + q_4 q_2\right) & 2\left(q_2 q_3 - q_4 q_1\right) & 1-2(q_{1}^{2}+q_{2}^{2}) + * \end{bmatrix} + * \f] + */ +void DirectionCosineMatrix::Set(const Quaternion& _qIn) +{ + // Calculations done for each element to increase speed + double q1 = _qIn(VectorIndexBase+0); + double q2 = _qIn(VectorIndexBase+1); + double q3 = _qIn(VectorIndexBase+2); + double q4 = _qIn(VectorIndexBase+3); + + // Column 1 + (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = q4*q4 + q1*q1 - q2*q2 - q3*q3; +// (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 1 - 2 * (q2*q2 + q3*q3); + (*this)(MatrixIndexBase+1,MatrixIndexBase+0) = 2 * (q1*q2 - q4*q3); + (*this)(MatrixIndexBase+2,MatrixIndexBase+0) = 2 * (q1*q3 + q4*q2); + + // Column 2 + (*this)(MatrixIndexBase+0,MatrixIndexBase+1) = 2 * (q1*q2 + q4*q3); + (*this)(MatrixIndexBase+1,MatrixIndexBase+1) = q4*q4 - q1*q1 + q2*q2 -q3*q3; +// (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 1 - 2 * (q1*q1 + q3*q3); + (*this)(MatrixIndexBase+2,MatrixIndexBase+1) = 2 * (q2*q3 - q4*q1); + + // Column 3 + (*this)(MatrixIndexBase+0,MatrixIndexBase+2) = 2 * (q1*q3 - q4*q2); + (*this)(MatrixIndexBase+1,MatrixIndexBase+2) = 2 * (q2*q3 + q4*q1); +// (*this)(MatrixIndexBase+0,MatrixIndexBase+0) = 1 - 2 * (q1*q1 + q2*q2); + (*this)(MatrixIndexBase+2,MatrixIndexBase+2) = q4*q4 - q1*q1 - q2*q2 + q3*q3; + + Normalize(); + return; +} + + /*! + * \brief Convert a DCM to a set of Euler Angles. + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + * @return (3 x 1) Euler Angles based on given rotation sequence. + */ +Vector DirectionCosineMatrix::GetEulerAngles(const int& _Sequence) const +{ + /*! \todo Implement DCM::GetEulerAngles function */ + return Vector(EULERANGLES_SIZE); +} + +/*! \brief Convert the DCM to an Euler Axis and Angle. + * @param _EulerAxis 3x1 Euler Axis vector (\f$\hat{e}\f$). + * @param _EulerAngle Angle rotation about axis (\f$\Phi\f$)[rad]. + * \par Equation: + * Ref Wertz, pg 413-4 + * \f[ \cos\Phi = \frac{1}{2}\left[tr\left(R\right)-1\right] \f] + * if \f$\sin\Phi \ne 0\f$, the componnets of \f$\hat{\bf e}\f$ are given by: + * \f[ + * e1 = (A_{23} - A_{32})/(2\sin\Phi) + * e2 = (A_{31} - A_{13})/(2\sin\Phi) + * e3 = (A_{12} - A_{21})/(2\sin\Phi) + * \f] + */ +void DirectionCosineMatrix::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const +{ + _EulerAngle = acos(0.5 * (trace(*this) - 1)); + if(sin(_EulerAngle) != 0) + { + _EulerAxis(VectorIndexBase + 0) = ((*this)(MatrixIndexBase+1,MatrixIndexBase+2) + - (*this)(MatrixIndexBase+1,MatrixIndexBase+2)) + / (2 * sin(_EulerAngle)); + _EulerAxis(VectorIndexBase + 1) = ((*this)(MatrixIndexBase+2,MatrixIndexBase+0) + - (*this)(MatrixIndexBase+0,MatrixIndexBase+2)) + / (2 * sin(_EulerAngle)); + _EulerAxis(VectorIndexBase + 2) = ((*this)(MatrixIndexBase+0,MatrixIndexBase+1) + - (*this)(MatrixIndexBase+0,MatrixIndexBase+1)) + / (2 * sin(_EulerAngle)); + } + else + { // no rotation, or rotation of 180 degs, therefore arbitrary axis. + _EulerAxis.setToValue(0.0); + _EulerAxis(VectorIndexBase + 0) = 1; + } + return; +} + +/*! \brief Convert a DCM to an MRP representation. + * This conversion is performed by creating a new instance of an MRP + * from this DCM. (\sa ModifiedRodriguezParameters::Set(DirectionCosineMatrix)) + * @return This conversion returns a (3 x 1) converted MRP. + */ +ModifiedRodriguezParameters DirectionCosineMatrix::GetMRP() const +{ + return ModifiedRodriguezParameters(*this); +} + +/*! \brief Convert a DCM to a quaternion representation. + * This conversion is performed by creating a new instance of a Quaternion + * from this DCM. (\sa Quaternion::Set(DirectionCosineMatrix)) + * @return This conversion returns a (4 x 1) converted quaternion. + */ +Quaternion DirectionCosineMatrix::GetQuaternion() const +{ + return Quaternion(*this); +} + +/*! \brief Normalize the Direction Cosine Matrix. + * This member function normalizes and stores the DCM. Normalization is performed + * by dividing each element in a column by the square-root of the sum of the squares of a column. + * \f[R_{ij}^{norm} = \frac{R_{ij}}{\sum_{k=1}^{k=3}{R_{ik}}}\f] + */ +void DirectionCosineMatrix::Normalize() +{ + double total = 0; + + for (int ii = MatrixIndexBase; ii < MatrixIndexBase + DCM_SIZE; ++ii) + { + total = sqrt(pow((*this)(ii, MatrixIndexBase),2) + + pow((*this)(ii, MatrixIndexBase+1),2) + + pow((*this)(ii, MatrixIndexBase+2),2)); + for (int jj = MatrixIndexBase; jj < MatrixIndexBase + DCM_SIZE; ++jj) + { + (*this)(ii, jj) /= total; + } + } + return; +} + + /*! \brief Determine the successive rotation from the summation of two DCMs. + * @param _DCM2 DCM to be summed with. + */ +DirectionCosineMatrix DirectionCosineMatrix::operator+ (const DirectionCosineMatrix& _DCM2) const +{ + return DirectionCosineMatrix(Matrix::operator+(static_cast(_DCM2))); +} + + /*! + * \brief Determine the relative rotation from the difference of two DCMs. + * @param _DCM2 DCM to be differenced with. + */ +DirectionCosineMatrix DirectionCosineMatrix::operator- (const DirectionCosineMatrix& _DCM2) const +{ + return DirectionCosineMatrix(Matrix::operator-(static_cast(_DCM2))); +} + +/*! \brief Determine the successive rotation of the DCMs through multiplication. + * @param _DCM2 DCM to be multiplied by. + */ +DirectionCosineMatrix DirectionCosineMatrix::operator* (DirectionCosineMatrix _DCM2) const +{ + return DirectionCosineMatrix(Matrix::operator*(static_cast(_DCM2))); +} + + /*! \brief Determine the rotation of a vector by a DCM. + * @param _DCM2 DCM to be multiplied by. + */ +inline Vector DirectionCosineMatrix::operator* (const Vector& _vec) const +{ + return Matrix::operator*(_vec); +} + + /*! \brief Determines the inverse of a DCM by taking the transpose (same operation). + * @return Inverse (transpose) of DCM. + */ +DirectionCosineMatrix DirectionCosineMatrix::operator~ () +{ + return DirectionCosineMatrix(Matrix::operator~()); +} + +/*! \brief Calculates the principal rotation of the angle about the 1-axis. + * \relates DirectionCosineMatrix + * \ingroup RotationLibrary + * @param _Angle Angle of Rotation [rad]. + * \par Equation: + * \f[ + * R_1\left(\theta\right) = + * \begin{bmatrix} + * 1 & 0 & 0\\ + * 0 & \cos{\theta} & \sin{\theta}\\ + * 0 & -\sin{\theta} & \cos{\theta} + * \end{bmatrix} + * \f] + */ +DirectionCosineMatrix R1(const Angle& _Angle) +{ + DirectionCosineMatrix R1_Out; + R1_Out(MatrixIndexBase+1, MatrixIndexBase+1) = cos(_Angle); + R1_Out(MatrixIndexBase+1, MatrixIndexBase+2) = sin(_Angle); + R1_Out(MatrixIndexBase+2, MatrixIndexBase+1) = -sin(_Angle); + R1_Out(MatrixIndexBase+2, MatrixIndexBase+2) = cos(_Angle); + return R1_Out; +} + +/*! \brief Calculates the principal rotation of the angle about the 2-axis. + * \relates DirectionCosineMatrix + * \ingroup RotationLibrary + * @param _Angle Angle of Rotation [rad]. + * \par Equation: + * \f[ + * R_2\left(\theta\right) = + * \begin{bmatrix} + * \cos{\theta} & 0 & -\sin{\theta}\\ + * 0 & 1 & 0\\ + * \sin{\theta} & 0 & \cos{\theta} + * \end{bmatrix} + * \f] + */ +DirectionCosineMatrix R2(const Angle& _Angle) +{ + DirectionCosineMatrix R2_Out; + R2_Out(MatrixIndexBase+0, MatrixIndexBase+0) = cos(_Angle); + R2_Out(MatrixIndexBase+0, MatrixIndexBase+2) = -sin(_Angle); + R2_Out(MatrixIndexBase+2, MatrixIndexBase+0) = sin(_Angle); + R2_Out(MatrixIndexBase+2, MatrixIndexBase+2) = cos(_Angle); + return R2_Out; +} + +/*! \brief Calculates the principal rotation of the angle about the 3-axis. + * \relates DirectionCosineMatrix + * \ingroup RotationLibrary + * @param _Angle Angle of Rotation [rad]. + * \par Equation: + * \f[ + * R_3\left(\theta\right) = + * \begin{bmatrix} + * \cos{\theta} & \sin{\theta} & 0\\ + * -\sin{\theta} & \cos{\theta} & 0\\ + * 0 & 0 & 1 + * \end{bmatrix} + * \f] + */ +DirectionCosineMatrix R3(const Angle& _Angle) +{ + DirectionCosineMatrix R3_Out; + R3_Out(MatrixIndexBase+0, MatrixIndexBase+0) = cos(_Angle); + R3_Out(MatrixIndexBase+0, MatrixIndexBase+1) = sin(_Angle); + R3_Out(MatrixIndexBase+1, MatrixIndexBase+0) = -sin(_Angle); + R3_Out(MatrixIndexBase+1, MatrixIndexBase+1) = cos(_Angle); + return R3_Out; +} + +////////////////////////////////////////////////////////////////////////// +// ModifiedRodriguezParameters Class + /*! \brief Default Constructor. + * \brief Create an MRP set with intial value of [0,0,0]^T. + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters():Vector(MRP_SIZE) +{ + AutoSwitch(); +} + + /*! \brief Copy Constructor. + * \brief Create a copy of an MRP set. + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters(const ModifiedRodriguezParameters& _MRP):Vector(MRP_SIZE) +{ + Set(_MRP); + AutoSwitch(); +} + + /*! \brief Create an MRP set based on 3 values. + * @param _s1 first MRP value. + * @param _s2 second MRP value. + * @param _s3 third MRP value. + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters(const double& _s1, const double& _s2, const double& _s3):Vector(MRP_SIZE) +{ + Set(_s1,_s2,_s3); + AutoSwitch(); +} + + /*! \brief Create an MRP set from a vector 3 values. + * @param _sVector 3x1 vector of MRP values. + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _sVector):Vector(MRP_SIZE) +{ + Set(_sVector); + AutoSwitch(); +} + + /*! \brief Create an MRP set converted from a Direction Cosine Matrix (DCM). + * @param _DCM 3x3 Direction Cosine Matrix (DCM) to be converted. + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters(const DirectionCosineMatrix& _DCM):Vector(MRP_SIZE) +{ + Set(_DCM); + AutoSwitch(); +} + + /*! \brief Create an MRP set from an Euler Angle sequence. + * @param _Angles 3x1 matrix of euler angles. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _Angles, const int& _Sequence):Vector(MRP_SIZE) +{ + Set(_Angles, _Sequence); + AutoSwitch(); +} + + /*! + * \brief Create the MRP from an Euler Axis and Angle. + * @param _EulerAxis 3x1 Euler Axis vector (\f$\hat{e}\f$). + * @param _EulerAngle Angle rotation about axis (\f$\Phi\f$)[rad]. + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Vector& _EulerAxis, const Angle& _EulerAngle):Vector(MRP_SIZE) +{ + Set(_EulerAxis, _EulerAngle); + AutoSwitch(); +} + + /*! \brief Create an MRP set converted from a quaternion. + * @param _DCM 4x1 quaternion to be converted. + */ +ModifiedRodriguezParameters::ModifiedRodriguezParameters(const Quaternion& _qIn):Vector(MRP_SIZE) +{ + Set(_qIn); + AutoSwitch(); +} + + /*! \brief Set the MRP to the copy of an existing MRP vector + * @param _MRP MRP Vector to be copied + */ +void ModifiedRodriguezParameters::Set(const ModifiedRodriguezParameters& _MRP) +{ + for(int ii = VectorIndexBase;ii < VectorIndexBase + MRP_SIZE; ++ii) + (*this)(ii) = _MRP(ii); + return; +} + + /*! \brief Set the MRP vector based on 3 values. + * @param _s1 first MRP value. + * @param _s2 second MRP value. + * @param _s3 third MRP value. + */ +void ModifiedRodriguezParameters::Set(const double& _s1, const double& _s2, const double& _s3) +{ + (*this)(VectorIndexBase+0) = _s1; + (*this)(VectorIndexBase+1) = _s2; + (*this)(VectorIndexBase+2) = _s3; + return; +} + + /*! \brief Set the MRP set from a vector 3 values. + * @param _sVector 3x1 vector of MRP values. + */ +void ModifiedRodriguezParameters::Set(const Vector& _sVector) +{ + for(int ii = VectorIndexBase;ii < VectorIndexBase + MRP_SIZE; ++ii) + (*this)(ii) = _sVector(ii); + return; +} + + /*! \brief Set the MRP from a converted Direction Cosine Matrix (DCM). + * @param _DCM 3x3 Direction Cosine Matrix (DCM) to be converted + */ +void ModifiedRodriguezParameters::Set(const DirectionCosineMatrix& _DCM) +{ + Set(_DCM.GetQuaternion()); + return; +} + + /*! \brief Set the MRP from the transformation of set of Euler Angles. + * @param _EulerAngles 3x1 matrix of Euler Angles. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +void ModifiedRodriguezParameters::Set(const Vector& _EulerAngles, const int& _Sequence) +{ + /*! \todo Change implementation to calculate directly from Euler angles and not create a DCM? */ + Set(DirectionCosineMatrix(_EulerAngles, _Sequence)); + return; +} + + /*! \brief Set the MRP from the transformation of set of Euler Angles. + * @param _Angle1 first angles in Euler angle set. [rad] + * @param _Angle2 second angles in Euler angle set. [rad] + * @param _Angle3 third angles in Euler angle set. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +void ModifiedRodriguezParameters::Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence) +{ + /*! \todo Fix Change implementation to calculate directly from Euler angles and not create a DCM? */ + Set(DirectionCosineMatrix(_Angle1, _Angle2, _Angle3, _Sequence)); + return; +} + + + /*! \brief Set the MRP from the transformation of an Euler Axis and Angle. + * @param _EulerAxis 3x1 Euler Axis vector (\f$\hat{e}\f$). + * @param _EulerAngle Angle rotation about axis (\f$\Phi\f$)[rad]. + * \par Equation: + * \f[ \bf{\sigma} = \tan{\frac{\phi}{4}}\bf{\hat{e}} \f] (Ref Schaub99) + * singluar whenever \f$\phi \rightarrow \pm 360^{\circ}\f$ + */ +void ModifiedRodriguezParameters::Set(const Vector& _EulerAxis, const Angle& _EulerAngle) +{ + (*this) = (ModifiedRodriguezParameters) (tan(0.25 * _EulerAngle) * _EulerAxis); + return; +} + + + /*! \brief Set the MRPs from a converted quaternion. + * @param _qIN 4x1 quaternion to be converted + * \par Equation: + * \f[\sigma_i = \frac{\bf{q}_i}{1+q_4}\f] for i=1,2,3 (Ref Schaub99) + * if q4 = -1, then q = -q. (prevent singularity) + */ +void ModifiedRodriguezParameters::Set(const Quaternion& _qIN) +{ + double denom = (1+_qIN(VectorIndexBase+3)); + if(denom == 0) + { + denom = 2; + (*this)(1) = (-_qIN(1) / denom); + (*this)(2) = (-_qIN(2) / denom); + (*this)(3) = (-_qIN(3) / denom); + } + else + { + (*this)(1) = (_qIN(1) / denom); + (*this)(2) = (_qIN(2) / denom); + (*this)(3) = (_qIN(3) / denom); + } + return; +} + + /*! \brief Convert the MRP vector to a Direction Cosine Matrix (DCM). + * @return 3x3 Direction Cosine Matrix. + */ +DirectionCosineMatrix ModifiedRodriguezParameters::GetDCM() const +{ + return DirectionCosineMatrix(*this); +} + + /*! \brief Convert the MRP vector to a set of Euler Angles. + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + * @return 3x1 vector of euler angles. + */ +Vector ModifiedRodriguezParameters::GetEulerAngles(int _Sequence) const +{ + /*! \todo Implement ModifiedRodriguezParameters::GetEulerAngles Function */ + return Vector(MRP_SIZE); +} + + /*! \brief Convert the MRP vector to the Euler Axis and Angle set. + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + * @return 3x1 vector of euler angles. + */ +void ModifiedRodriguezParameters::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const +{ + /*! \todo Implement to directly convert and not use a temporary quaternion */ + Quaternion qTemp(*this); + qTemp.GetEulerAxisAngle(_EulerAxis, _EulerAngle); + return; +} + + /*! \brief Convert the MRP vector to a quaternion. + * @return 4x1 quaternion. + */ +Quaternion ModifiedRodriguezParameters::GetQuaternion() const +{ + return Quaternion(*this); +} + + /*! \brief Switches the MRP vector to the shortest rotational distance back to the origin + * using the shadow set if the magnitude of the vector is greater than the input value S. + * @param _SwitchThreshold magnitude of the MRP vector at which the set is switched. A positive scalar number. + */ +void ModifiedRodriguezParameters::Switch(int _SwitchThreshold) +{ + if (norm2((Vector)*this) > _SwitchThreshold) + (*this) = ShadowSet(); + return; +} + + /*! \brief Sets the MRP set to automatically switch between the normal set and the shadow set + * based on the shortest rotational distance to the origin. + * @param _SwitchBoolean boolean value where TRUE turns on switching, and FALSE turns off switching. + */ +void ModifiedRodriguezParameters::AutoSwitch(bool _SwitchBoolean) +{ + m_AutoSwitch = _SwitchBoolean; + return; +} + + + /*! \brief Calculates and returns the MRP shadow set. + * @return MRP shadow set (3x1). + * \par Equation: + * The equation for computer the MRP shadow set is: + * \f[ \bf{\sigma}^{S} = - \frac{1}{|\bf{\sigma}|^2}\bf{\sigma} \f] + * (Ref Schaub99) + */ +ModifiedRodriguezParameters ModifiedRodriguezParameters::ShadowSet() const +{ + return (ModifiedRodriguezParameters)(-(*this)(_) / pow(norm2(*this),2)); +} + + + /*! \brief Determine the successive rotation from the summation of two MRP vectors. + * @param _MRP2 MRP vector to be summed with. + * \par Equation: + * Summing two MRP vectors \f$\bf{\sigma'}\f$ and \f$\bf{\sigma''}\f$: + * \f[ + * \bf{\sigma} = \frac{(1-|\bf{\sigma'}|^2)\bf{\sigma''}+(1-|\bf{\sigma''}|^2)\bf{\sigma'}-2\bf{\sigma''} \times \bf{\sigma'}}{1+|\bf{\sigma'}|^2|\bf{\sigma''}|^2-2\bf{\sigma'} \dot \bf{\sigma''}} + * \f] + */ +ModifiedRodriguezParameters ModifiedRodriguezParameters::operator+ (const ModifiedRodriguezParameters& _MRP2) const +{ + ModifiedRodriguezParameters MRPsum; + MRPsum(_) = (1-pow(norm2(*this),2)) * _MRP2 + + (1-pow(norm2(_MRP2),2)) * (*this) + - 2*crossP(_MRP2,(*this)); + MRPsum(_) = MRPsum / (1 + pow(norm2(*this),2) * pow(norm2(_MRP2),2) + - 2 * (*this).dot( _MRP2)); + return MRPsum; +} + + + /*! \brief Determine the relative rotation from the difference of two MRP vectors. + * @param _MRP2 MRP vector to be differenced with. + * \par Equation: + * Relative MRP vector \f$\bf{\sigma''} = \bf{\sigma} - \bf{\sigma'}\f$ (Ref Schaub99): + * \f[ + * \bf{\sigma''} = \frac{\left(1-\left|\bf{\sigma'}\right|^2\right)\bf{\sigma}-\left(1-\left|\bf{\sigma}\right|^2\right)\bf{\sigma'}+2\bf{\sigma} \times \bf{\sigma'}}{1+\left|\bf{\sigma'}\right|^2\left|\bf{\sigma}\right|^2+2\bf{\sigma'} \dot \bf{\sigma}} + * \f] + */ +ModifiedRodriguezParameters ModifiedRodriguezParameters::operator- (const ModifiedRodriguezParameters& _MRP2) const +{ + ModifiedRodriguezParameters MRPsum; + MRPsum(_) = (1-pow(norm2(_MRP2),2)) * (*this) + + (1-pow(norm2(*this),2)) * _MRP2 + - 2*crossP((*this), _MRP2); + MRPsum(_) = MRPsum / ((1 + pow(norm2(_MRP2),2)) * pow(norm2(*this),2) + - 2 * _MRP2.dot(*this)); + return MRPsum; +} + +////////////////////////////////////////////////////////////////////////// +// Quaternion Class + /*! \brief Create a quaternion with initial value of [0,0,0,1]^T. + * @return (double) - (4 x 1) quaternion = [0,0,0,1]^T. + */ +Quaternion::Quaternion():Vector(QUATERNION_SIZE) +{ +// (*this).setToValue(0.0); + (*this)(VectorIndexBase+3) = 1.0; +} + + /*! \brief Create a quaternion with initial values; will be normalized to a unit quaternion automatically. + * @param _q1 first quaternion parameter + * @param _q2 second quaternion parameter + * @param _q3 third quaternion parameter + * @param _q4 fourth quaternion parameter + * @return (double) - (4 x 1) quaternion = [_q1,_q2,_q3,_q4]^T. + */ +Quaternion::Quaternion(double _q1, double _q2, double _q3, double _q4):Vector(QUATERNION_SIZE) +{ + Set(_q1, _q2, _q3, _q4); +} + + /*! \brief Create a quaternion with initial value of the input 4x1 matrix. + * @param _qMatrix 4x1 matrix of quaternion elements. + * @return (double) - (4 x 1) quaternion. + */ +/* +Quaternion::Quaternion(const Matrix& _qMatrix):Vector(QUATERNION_SIZE) +{ + Set(_qMatrix); +} +*/ + + /*! + * \brief Create a quaternion with initial value of the input 4x1 vector; will be normalized to a unit quaternion automatically. + * @param _qMatrix 4x1 vector of quaternion elements. + * @return (double) - (4 x 1) quaternion. + */ +Quaternion::Quaternion(const Vector& _qVector):Vector(QUATERNION_SIZE) +{ + Set(_qVector); +} + + /*! + * \brief Create a quaternion from a direction cosine matrix (DCM). + * @param _DCM 3x3 Direction Cosine Matrix to be transformed. + * @return (double) - (4 x 1) quaternion. + */ +Quaternion::Quaternion(const DirectionCosineMatrix& _DCM):Vector(QUATERNION_SIZE) +{ + Set(_DCM); +} + + /*! \brief Create a quaternion from a set of Euler Angles and Sequence. + * @param _EulerAngles 3x1 matrix of Euler Angles. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +Quaternion::Quaternion(const Vector& _EulerAngles, const int& _Sequence):Vector(QUATERNION_SIZE) +{ + Set(_EulerAngles, _Sequence); + Normalize(); +} + + /*! \brief Create a quaternion from the transformation about an Euler Axis by a set angle. + * @param _EulerAxis 3x1 Euler Axis vector. + * @param _EulerAngle Angle rotation about axis [rad]. + */ +Quaternion::Quaternion(const Vector& _EulerAxis, const Angle& _EulerAngle):Vector(QUATERNION_SIZE) +{ + Set(_EulerAxis, _EulerAngle); +} + + /*! \brief Create a Quaternion from the transformation of Modified Rodriguez Paramaters (MRP). + * @param _MRP 3x1 matrix of Modified Rodriguez Parameters (MRP). + */ +Quaternion::Quaternion(const ModifiedRodriguezParameters& _MRP):Vector(QUATERNION_SIZE) +{ + Set(static_cast(_MRP)); +} + + /*! \brief Set the quaternion to a copy of another quaternion. + * @param _qIn Quaternion to be copied. + */ +void Quaternion::Set(const Quaternion& _qIn) +{ + (*this)(VectorIndexBase+0) = _qIn(MatrixIndexBase+0); + (*this)(VectorIndexBase+1) = _qIn(MatrixIndexBase+1); + (*this)(VectorIndexBase+2) = _qIn(MatrixIndexBase+2); + (*this)(VectorIndexBase+3) = _qIn(MatrixIndexBase+3); + Normalize(); + return; +} + + /*! \brief Sets the quaternion to the values specified. + * @param _q1 first quaternin parameter + * @param _q2 second quaternin parameter + * @param _q3 third quaternin parameter + * @param _q4 fourth quaternin parameter + */ +void Quaternion::Set(double _q1, double _q2, double _q3, double _q4) +{ + (*this)(VectorIndexBase+0) = _q1; + (*this)(VectorIndexBase+1) = _q2; + (*this)(VectorIndexBase+2) = _q3; + (*this)(VectorIndexBase+3) = _q4; + Normalize(); + return; +} + + /*! \brief Sets the quaternion with the values of the input 4x1 matrix. + * @param _qMatrix 4x1 matrix of quaternion elements. + */ +/* +void Quaternion::Set(const Matrix& _qMatrix) +{ + if((_qMatrix[MatrixRowsIndex].getIndexBound() == QUATERNION_SIZE) && (_qMatrix[MatrixColsIndex].getIndexBound() == 1)) + { + (*this)(VectorIndexBase+0) = _qMatrix(MatrixIndexBase+0,MatrixIndexBase); + (*this)(VectorIndexBase+1) = _qMatrix(MatrixIndexBase+1,MatrixIndexBase); + (*this)(VectorIndexBase+2) = _qMatrix(MatrixIndexBase+2,MatrixIndexBase); + (*this)(VectorIndexBase+3) = _qMatrix(MatrixIndexBase+3,MatrixIndexBase); + } + else + { + (*this) = Quaternion(); + } + return; +}*/ + + /*! \brief Sets the quaternion with the values of the input 4x1 vector. + * @param _qMatrix 4x1 vector of quaternion elements. + */ +void Quaternion::Set(const Vector& _qVector) +{ + (*this)(VectorIndexBase+0) = _qVector(MatrixIndexBase+0); + (*this)(VectorIndexBase+1) = _qVector(MatrixIndexBase+1); + (*this)(VectorIndexBase+2) = _qVector(MatrixIndexBase+2); + (*this)(VectorIndexBase+3) = _qVector(MatrixIndexBase+3); + Normalize(); + return; +} + + +/*! \brief Sets the current quaternion from a converted Direction Cosine Matrix (DCM). + * @param _DCM 3x3 DCM to be converted. + * \par Equation: + * Ref Hughes p. 18 + * \f[q_4 = \pm \frac{1}{2}\left(1+R_{11}+R_{22}+R_{33}\right)^{\frac{1}{2}}\f] + * \f[ + * \bf{q} = \frac{1}{4q_4} + * \begin{bmatrix} + * R_{23}-R{32} \\ R_{31}-R{13} \\ R_{12}-R{21} + * \end{bmatrix}\f]\f[ + * \bf{\bar{q}} = \begin{bmatrix} \bf{q} \\ q_4 \end{bmatrix} + * \f] + */ +void Quaternion::Set(const DirectionCosineMatrix& _DCM) +{ + (*this)(VectorIndexBase+3) = 0.5 * sqrt(1 + trace(_DCM)); + (*this)(VectorIndexBase+0) = _DCM(MatrixIndexBase+1,MatrixIndexBase+2) + - _DCM(MatrixIndexBase+2,MatrixIndexBase+1); + (*this)(VectorIndexBase+1) = _DCM(MatrixIndexBase+2,MatrixIndexBase+0) + - _DCM(MatrixIndexBase+0,MatrixIndexBase+2); + (*this)(VectorIndexBase+2) = _DCM(MatrixIndexBase+0,MatrixIndexBase+1) + - _DCM(MatrixIndexBase+1,MatrixIndexBase+0); + (*this)(_(VectorIndexBase,VectorIndexBase+2)) /= (4 * (*this)(VectorIndexBase+3)); + Normalize(); + return; +} + + /*! \brief Set the quaternion to the transformation of set of Euler Angles. + * @param _EulerAngles 3x1 matrix of Euler Angles. [rad] + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + */ +void Quaternion::Set(const Vector& _EulerAngles, const int& _Sequence) +{ + /*! \todo Implement Quaternion::Set(EulerAngles, Sequence) as individual calcs instead of multiple conversions */ + Set(DirectionCosineMatrix(_EulerAngles, _Sequence)); + Normalize(); + return; +} + + + /*! \brief Set the quaternion to the transformation about an Euler Axis by a set angle. + * @param _EulerAxis 3x1 Euler Axis vector (\f$\hat{e}\f$). + * @param _EulerAngle Angle rotation about axis (\f$\Phi\f$)[rad]. + * \par Equation: + * \f[ \bf{q}_i = \hat{e}_i \sin{\frac{\Phi}{2}} q_4 = \cos{\frac{\Phi}{2}} \f] + * for i=1,2,3 + */ +void Quaternion::Set(const Vector& _EulerAxis, const Angle& _EulerAngle) +{ + (*this)(_(VectorIndexBase+0,VectorIndexBase+2)) = _EulerAxis * sin(0.5 * _EulerAngle); + (*this)(VectorIndexBase+3) = cos(0.5 * _EulerAngle); + Normalize(); + return; +} + + +/*! \brief Set the Quaternion to the transformation of Modified Rodriguez Paramaters (MRP). + * @param _MRP 3x1 matrix of Modified Rodriguez Parameters (MRP). + * \par Equation: + * \f[ \bf{q}_i = \frac{2\sigma_i}{1+\sigma^2} q_4 = \frac{1-\sigma^2}{1+\sigma^2} \f] + * for i=1,2,3 (Ref Schaub99) + */ +void Quaternion::Set(const ModifiedRodriguezParameters& _MRP) +{ + Matrix tempMatrix = (~_MRP) * (_MRP); + double sigmaSq = tempMatrix(MatrixIndexBase,MatrixIndexBase); + double denom = 1 + sigmaSq; + (*this)(1) = 2 * _MRP(1) / denom; + (*this)(2) = 2 * _MRP(2) / denom; + (*this)(3) = 2 * _MRP(3) / denom; + (*this)(VectorIndexBase+3) = (1 - sigmaSq) /denom; + Normalize(); + return; +} + + /*! \brief Convert the quaternion to a Direction Cosine Matrix (DCM). + * Uses the DirectionCosineMatrix(Quaternion) constructor. + * @return 3x3 Direction Cosine Matrix. + */ +DirectionCosineMatrix Quaternion::GetDCM() const +{ + return DirectionCosineMatrix(*this); +} + + /*! \brief Convert the quaternion to a set of Euler Angles. + * @param _Sequence Euler angle rotation sequence. (ie 123, 213, 313, 321, etc). + * @return (3 x 1) Euler Angles based on given rotation sequence (\f$\theta_i\f$)[rad] + */ +Vector Quaternion::GetEulerAngles(const int& _Sequence) const +{ + /*! \todo Implement Quaternion::GetEulerAngles function */ + return Vector(EULERANGLES_SIZE); +} + + +/*! \brief Convert the quaternion to an Euler Axis and Angle. + * @param _EulerAxis 3x1 Euler Axis vector (\f$\hat{e}\f$). + * @param _EulerAngle Angle rotation about axis (\f$\Phi\f$)[rad]. + * @return 4-element vector [EulerAxis; EulerAngle] + * \par Equation: + * \f[\Phi = 2\cos^{-1}{q_4} \hat{e}_i = \bf{q}_i\sin{\frac{\Phi}{2}}\f] + * (Ref Schaub99) + */ +Vector Quaternion::GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const +{ + Vector returnVector(EULERAXIS_SIZE + 1); + _EulerAngle = 2.0 * acos((*this)(VectorIndexBase+3)); + _EulerAxis = (*this)(_(VectorIndexBase+0,VectorIndexBase+2)) * sin(0.5 * _EulerAngle); + returnVector(_(VectorIndexBase,VectorIndexBase+EULERAXIS_SIZE-1)) = _EulerAxis; + returnVector(VectorIndexBase + EULERAXIS_SIZE) = _EulerAngle; + return returnVector; +} + + + /*! \brief Convert the quaternion to an Euler Axis and Angle. + * @return 4-element vector [EulerAxis; EulerAngle] + */ +Vector Quaternion::GetEulerAxisAngle() const +{ + Vector EulerAxis(EULERAXIS_SIZE); + double EulerAngle; + return GetEulerAxisAngle(EulerAxis, EulerAngle); +} + + + /*! \brief Convert the quaternion to an MRP representation. + * Uses the ModifiedRodriguezParameters(Quaternion) constructor. + * @return (3 x 1) converted MRP. + */ +ModifiedRodriguezParameters Quaternion::GetMRP() const +{ + return ModifiedRodriguezParameters(*this); +} + + + /*! \brief Normalizes a quaternion so that \f${\bf{\bar q}}^T {\bf{\bar q}}=1$\f. + */ +void Quaternion::Normalize() +{ + /*! \todo Add Normalize() to Vector Class */ + normalize(*this); + return; +} + +/*! \brief Determine the successive rotation from the summation of two quaternions. + * @param _quat2 Quaternion to be summed with. + * + * \par Equation: + * successive rotations of \f$\bf{q'}\f$ and \f$\bf{q''}\f$ (Ref Schaub99) + * \f[ + * \begin{bmatrix} + * q_1 \\ q_2 \\ q_3 \\ q_4 + * \end{bmatrix} + * = + * \begin{bmatrix} + * q'_1 & q'_4 & -q'_3 & q'_2\\ + * q'_2 & q'_3 & q'_4 & -q'_1\\ + * q'_3 & -q'_2 & q'_1 & q'_4\\ + * q'_4 & -q'_1 & -q'_2 & -q'_3 + * \end{bmatrix} + * \begin{bmatrix} + * q''_1 \\ q''_2 \\ q''_3 \\ q''_4 + * \end{bmatrix} + * \f] + */ +Quaternion Quaternion::operator+ (const Quaternion& _quat2) const +{ + Matrix qSkewed(4,4); + // Column 1 + qSkewed(_,MatrixIndexBase+0) = (*this); + // Column 2 + qSkewed(MatrixIndexBase+0,MatrixIndexBase+1) = (*this)(VectorIndexBase+0); + qSkewed(MatrixIndexBase+1,MatrixIndexBase+1) = (*this)(VectorIndexBase+2); + qSkewed(MatrixIndexBase+2,MatrixIndexBase+1) = -(*this)(VectorIndexBase+1); + qSkewed(MatrixIndexBase+3,MatrixIndexBase+1) = -(*this)(VectorIndexBase+3); + // Column 3 + qSkewed(MatrixIndexBase+0,MatrixIndexBase+2) = -(*this)(VectorIndexBase+1); + qSkewed(MatrixIndexBase+1,MatrixIndexBase+2) = (*this)(VectorIndexBase+2); + qSkewed(MatrixIndexBase+2,MatrixIndexBase+2) = (*this)(VectorIndexBase+3); + qSkewed(MatrixIndexBase+3,MatrixIndexBase+2) = -(*this)(VectorIndexBase+0); + // Column 4 + qSkewed(MatrixIndexBase+0,MatrixIndexBase+3) = (*this)(VectorIndexBase+1); + qSkewed(MatrixIndexBase+1,MatrixIndexBase+3) = -(*this)(VectorIndexBase+0); + qSkewed(MatrixIndexBase+2,MatrixIndexBase+3) = (*this)(VectorIndexBase+3); + qSkewed(MatrixIndexBase+3,MatrixIndexBase+3) = -(*this)(VectorIndexBase+2); + + return Quaternion(qSkewed * _quat2); +} + +/*! \brief Determine the relative rotation from the difference of two quaternions. + * @param _quat2 Quaternion to be differenced with. + * + * \par Equation: + * subtracting \f$\bf{q'}\f$ from \f$\bf{q''}\f$ (Ref Schaub99) + * \f[ + * \begin{bmatrix} + * q_1 \\ q_2 \\ q_3 \\ q_4 + * \end{bmatrix} + * = + * \begin{bmatrix} + * -q'_4 & q'_4 & q'_3 & -q'_2\\ + * -q'_2 & -q'_3 & q'_4 & q'_1\\ + * -q'_3 & -q'_2 & -q'_1 & q'_4\\ + * q'_4 & q'_1 & q'_2 & q'_3 + * \end{bmatrix} + * \begin{bmatrix} + * q''_1 \\ q''_2 \\ q''_3 \\ q''_4 + * \end{bmatrix} + * \f] + */ +Quaternion Quaternion::operator- (const Quaternion& _quat2) const +{ + Matrix qSkewed(4,4); + // Column 1 + qSkewed(MatrixIndexBase+0,MatrixIndexBase+0) = -_quat2(VectorIndexBase+0); + qSkewed(MatrixIndexBase+1,MatrixIndexBase+0) = -_quat2(VectorIndexBase+1); + qSkewed(MatrixIndexBase+2,MatrixIndexBase+0) = -_quat2(VectorIndexBase+2); + qSkewed(MatrixIndexBase+3,MatrixIndexBase+0) = _quat2(VectorIndexBase+3); + // Column 2 + qSkewed(MatrixIndexBase+0,MatrixIndexBase+1) = _quat2(VectorIndexBase+3); + qSkewed(MatrixIndexBase+1,MatrixIndexBase+1) = -_quat2(VectorIndexBase+2); + qSkewed(MatrixIndexBase+2,MatrixIndexBase+1) = _quat2(VectorIndexBase+1); + qSkewed(MatrixIndexBase+3,MatrixIndexBase+1) = _quat2(VectorIndexBase+0); + // Column 3 + qSkewed(MatrixIndexBase+0,MatrixIndexBase+2) = _quat2(VectorIndexBase+2); + qSkewed(MatrixIndexBase+1,MatrixIndexBase+2) = _quat2(VectorIndexBase+3); + qSkewed(MatrixIndexBase+2,MatrixIndexBase+2) = -_quat2(VectorIndexBase+0); + qSkewed(MatrixIndexBase+3,MatrixIndexBase+2) = _quat2(VectorIndexBase+1); + // Column 4 + qSkewed(MatrixIndexBase+0,MatrixIndexBase+3) = -_quat2(VectorIndexBase+1); + qSkewed(MatrixIndexBase+1,MatrixIndexBase+3) = _quat2(VectorIndexBase+0); + qSkewed(MatrixIndexBase+2,MatrixIndexBase+3) = _quat2(VectorIndexBase+3); + qSkewed(MatrixIndexBase+3,MatrixIndexBase+3) = _quat2(VectorIndexBase+2); + + return Quaternion((qSkewed) * (*this)); +} +} // end of namespace O_SESSAME +/*!*************************************************************************** +* $Log: Rotation.cpp,v $ +* Revision 1.24 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.23 2003/06/10 14:23:42 nilspace +* Changed MRP::Set(Quaternion) to not overwrite the const. +* +* Revision 1.22 2003/06/10 02:25:32 nilspace +* Fixed MRP::Set(Quaternion) since there apparently is no Vector::operator-() that returns the negative of a Vector. +* +* Revision 1.21 2003/05/27 20:01:38 nilspace +* Fixed numerous bugs with MRP conversion functions. +* +* Revision 1.20 2003/05/27 14:39:12 nilspace +* Fixed the MRP->Quaternion conversion. +* +* Revision 1.19 2003/05/22 03:03:38 nilspace +* Update documentation, and changed all angles to use Angle type. +* +* Revision 1.18 2003/05/21 22:18:05 nilspace +* Moved the documentation to the implementation file. +* +* Revision 1.17 2003/05/20 17:53:51 nilspace +* Updated comments. +* +* Revision 1.16 2003/05/13 19:45:10 nilspace +* Updated comments. +* +* Revision 1.15 2003/05/02 19:44:24 nilspace +* Modified the DCM::Set(Quaternion) function for a more efficient calculation on the diagonals. +* +* Revision 1.14 2003/04/28 14:16:26 nilspace +* Moved all function definitions out of header file into implementation file. +* +* Revision 1.13 2003/04/27 20:41:09 nilspace +* Encapsulated the rotation library into the namespace O_SESSAME. +* +* Revision 1.12 2003/04/22 21:59:58 nilspace +* Fixed Quaternion::Set(DCM) so it evaluates correctly. +* Implemented Rotation::operator-() +* +* Revision 1.11 2003/04/22 20:52:39 nilspace +* Added Normalize() call to all of the DCM::Set functions. +* +* Revision 1.10 2003/04/22 19:45:16 nilspace +* Fixed DCM::Set to correctly calculate the MRP tempMatrix (sigma^2) +* +* Revision 1.9 2003/04/22 19:36:02 nilspace +* Various bug fixes to DCM & quaternion conversions. Added DirectionCosineMatrix Normalize(). +* +* Revision 1.8 2003/04/22 16:03:11 nilspace +* Updated MRP::Set(Quaternion) to correctly set. +* +* Revision 1.7 2003/04/10 17:25:51 nilspace +* changelog +* +* Revision 1.6 2003/04/08 23:02:27 nilspace +* Added Rotation Sense, or "Handedness". Defaults to RIGHT_HAND +* +* Revision 1.5 2003/03/27 20:22:26 nilspace +* Added GetRotation() function. +* Fixed Quaternion.Set(Quaternion) function. +* Added RotationType enum. +* Made sure to normalize the Quaternions for all the Set() functions. +* +* Revision 1.4 2003/03/25 02:37:36 nilspace +* Added quaternion matrix set and constructor. +* Added Rotation generalized matrix set to check for quaternion. +* +* Revision 1.3 2003/03/04 17:36:19 nilspace +* Added CVS tags for documenting uploads. Also chmod'd to not be executable. +* +* Revision 1.1 2003/02/27 18:37:26 nilspace +* Initial submission of Rotation class implementation. +* +* +******************************************************************************/ + diff --git a/src/rotation/Rotation.h b/src/rotation/Rotation.h new file mode 100755 index 0000000..23eff93 --- /dev/null +++ b/src/rotation/Rotation.h @@ -0,0 +1,541 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Rotation.h + * \brief Rotation toolkit. + * \brief Provides a set of functions to use Rotation matrices + * and their various representations. + * \author $Author: rsharo $ + * \version $Revision: 1.19 $ + * \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Implement Gibbs vector representation + */ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __OSESSAME_ROTATION_H__ +#define __OSESSAME_ROTATION_H__ +#include "matrix/Matrix.h" +#include +#include "utils/MathUtils.h" +using namespace O_SESSAME; + +namespace O_SESSAME { +// Prototype definitions of classes in Rotation Toolbox +class Quaternion; +class DirectionCosineMatrix; +class ModifiedRodriguezParameters; +class Rotation; + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \defgroup RotationLibrary Rotation Library +* The Rotation Library is a collection of attitude representation class definitions that are meant to +* assist in the implementation of spacecraft analysis and operation code. Each attitude representation +* is implemented as a class with member functions that perform transformations and retrievals of the +* rotation information. +* +* The Rotation class is the most general, and useful, of the Kinematics Toolbox classes. All +* attitudes can be stored as a Rotation, and then retrieved in any of the desired formats +* (MRP, DCM, Quaternion, Euler Axis & Angle, Euler Angle). +* +* Here are some examples of using the kinematics toolbox in general. For more specific examples +* refer to the appropriate classes documentation. +* \par Examples: +* +\code +DirectionCosineMatrix dcm1(deg2rad(30),deg2rad(-10),deg2rad(5), 123); // create a DCM with successive rotations of [30,-10,5] degs in a 123 rotation order +Quaternion q1(dcm1); // create a quaternion that is the same attitude transformation as dcm1 +Quaternion q2(~dcm1); // create a second quaternion that is the transpose of dcm1 (~dcm1) +Rotation rot1(q1 * q2); // create a rotation that is the successive rotation of q1 and q2 +cout << rot1; // output rot1 to the standard stream (usually the screen) +\endcode +\code +Vector eulerAxis; +double eulerAngle; +rot1.GetEulerAxisAngle(eulerAxis, eulerAngle); +cout << eulerAxis << eulerAngle; +\endcode +* +* \example testRotation.cpp +* Demonstrates the use of the Rotation class and associated kinematic representations. +* @{ +*/ + +/*! \brief Number of elements in a quaternion vector */ +const int QUATERNION_SIZE = 4; +/*! \brief Number of elements in a MRP vector */ +const int MRP_SIZE = 3; +/*! \brief Number of elements in a DCM row or column */ +const int DCM_SIZE = 3; +/*! \brief Number of elements in an euler axis */ +const int EULERAXIS_SIZE = 3; +/*! \brief Number of elements in an euler angle sequence */ +const int EULERANGLES_SIZE = 3; + +/*! \brief Various representations of a rotation */ +enum RotationType{DCM_Type, EulerAngle_Type, EulerAxisAngle_Type, MRP_Type, Quaternion_Type}; + +/*! \brief The Sense, or "handedness" of a rotation system */ +enum RotationSense{LEFT_HAND = -1, RIGHT_HAND = 1}; + +/** @} */ + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \brief 3x3 direction cosine matrix attitude representation. +* \ingroup RotationLibrary +* +* +* A simple way to describe and represent an Euler Angle sequence is by the use of a Direction Cosine Matrix (DCM). A DCM is a 3x3 matrix of values, a rotation matrix, that represent the transformation of a vector from one coordinate frame to another: +\f[ + +{\bf v}^{b} = {\bf R}^{ba}{\bf v}^{a} + +\f] +where \f${\bf v}^{a}\f$ and \f${\bf v}^{b}\f$ are the \f$\hat{\bf v}\f$ vectors in \f$\mathcal{F}_{a}\f$ (Frame {\it a\/}) and \f$\mathcal{F}_{b}\f$ respectively. \f${\bf R}^{ba}\f$ is the DCM describing the rotation from \f$\mathcal{F}_{a}\f$ to \f$\mathcal{F}_{b}\f$. + +The direction cosine matrix is constructed by the components of the angles between the frame axes: +\f[ +{\bf R}^{21} = \begin{bmatrix} +\cos{\theta_{x_{2}x_{1}}} && \cos{\theta_{x_{2}y_{1}}} && \cos{\theta_{x_{2}z_{1}}}\\ +\cos{\theta_{y_{2}x_{1}}} && \cos{\theta_{y_{2}y_{1}}} && \cos{\theta_{y_{2}z_{1}}}\\ +\cos{\theta_{z_{2}x_{1}}} && \cos{\theta_{z_{2}y_{1}}} && \cos{\theta_{z_{2}z_{1}}}\end{bmatrix} +\f] +where \f$\cos{\theta_{x_{2}x_{1}}}\f$ is the cosine of the angle between the \f$x\f$ axis of the first frame and the \f$x\f$ axis of the second frame. + +To determine successive rotations (say from \f$\mathcal{F}_{a}\f$ to \f$\mathcal{F}_{b}\f$ to \f$\mathcal{F}_{c}\f$), we can simply combine the rotation matrices by multiplying them together: +\f[ +{\bf R}^{ca} = {\bf R}^{cb}{\bf R}^{ba} +\f] + +


+A DCM can be created from any of the other attitude representations +\code +DirectionCosineMatrix myEulerDCM(40*RPD, 20*RPD, -120*RPD, 312); // creates a 312 rotation DCM from 3 euler angles +DirectionCosineMatrix myQuatDCM(myQuaternion); // where myQuaternion is an instance of Quaternion +DirectionCosineMatrix myMRPDCM(myMRP); // where myMRP is an instance of ModifiedRodriguezParameters +\endcode + +and can also return the transformation in any of the representations. The successive and relative rotations +* between 2 DCMS can be computed: +\code +dcm3 = dcm1 * dcm2; \\ successive rotation +dcm3 = dcm1 + dcm2; \\ successive rotation +dcm1 = dcm3 - dcm2; \\ relative rotation +\endcode +* If the inverse transformation of a direction cosine matrix is required, the transpose operation +* is used: +\code +dcmOI = ~dcmIO; +\endcode +* +* The DirectionCosineMatrix class is derived from Matrix, so therefore includes all +* of the functionality of the Matrix class. This includes subarray accessing, element +* accessing, multiplication, addition (except where redefined by the subclass). +\code +double element11 = dcm1(MatrixBaseIndex + 0, MatrixBaseIndex + 0); +Vector column2 = dcm1(_,MatrixBaseIndex+1); +\endcode +* +*/ +class DirectionCosineMatrix:public Matrix +{ +public: + + // DCM CONSTROCTURS + DirectionCosineMatrix(); + + DirectionCosineMatrix(const DirectionCosineMatrix& _DCM); + + DirectionCosineMatrix(const Matrix& _DCM); + + DirectionCosineMatrix(const Vector& _EulerAngles, const int& _Sequence); + + DirectionCosineMatrix(const Vector& _EulerAxis, const Angle& _EulerAngle); + + DirectionCosineMatrix(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); + + DirectionCosineMatrix(const ModifiedRodriguezParameters& _MRP); + + DirectionCosineMatrix(const Quaternion& _quat); + + virtual ~DirectionCosineMatrix(); + + // DCM MUTATORS + void Set(const DirectionCosineMatrix& _DCM); + + void Set(const Matrix& _DCM); + + void Set(const Vector& _EulerAngles, const int& _Sequence); + + void Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); + + void Set(const Vector& _EulerAxis, const Angle& _EulerAngle); + + void Set(const ModifiedRodriguezParameters& _MRP); + + void Set(const Quaternion& _qIn); + + // DCM INSPECTORS + Vector GetEulerAngles(const int& _Sequence) const; + + void GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; + + ModifiedRodriguezParameters GetMRP() const; + + Quaternion GetQuaternion() const; + + // DCM OPERATORS + void Normalize(); + + DirectionCosineMatrix operator+ (const DirectionCosineMatrix& _DCM2) const; + + DirectionCosineMatrix operator- (const DirectionCosineMatrix& _DCM2) const; + + inline DirectionCosineMatrix operator* (DirectionCosineMatrix _DCM2) const; + + inline Vector operator* (const Vector& _vec) const; + + inline DirectionCosineMatrix operator~ (); + +}; + + +DirectionCosineMatrix R1(const Angle& _Angle); + +DirectionCosineMatrix R2(const Angle& _Angle); + +DirectionCosineMatrix R3(const Angle& _Angle); +// end of DirectionCosineMatrix + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \brief 3x1 Modified Rodriguez Parameters attitude representation. +* \ingroup RotationLibrary +* +Another method of specifying a rigid body attitude is through the +use of Modified Rodriguez Parameters (MRP). The 3-element set is +defined as follows: +\f[ +{\bf \sigma} = \hat{\bf e}\tan{\frac{\Phi }{4}}. +\f] +Like the quaternions, the MRP is not a unique solution to the transformation, but also has a shadow set, \f${\bf \sigma}^{S}\f$: +\f[ +{\bf \sigma}^{S} = -\frac{1}{|{\bf \sigma}^{2}}{\bf \sigma} +\f] +This can be evaluated whenever \f$|{\bf \sigma}| > 1\f$ since the shadow set will be a shorter rotational distance back to the original frame. + +*/ +class ModifiedRodriguezParameters:public Vector +{ +public: + // MRP CONSTRUCTORS + ModifiedRodriguezParameters(); + + ModifiedRodriguezParameters(const ModifiedRodriguezParameters& _MRP); + + ModifiedRodriguezParameters(const double& _s1, const double& _s2, const double& _s3); + + ModifiedRodriguezParameters(const Vector& _sVector); + + ModifiedRodriguezParameters(const DirectionCosineMatrix& _DCM); + + ModifiedRodriguezParameters(const Vector& _Angles, const int& _Sequence); + + ModifiedRodriguezParameters(const Vector& _EulerAxis, const Angle& _EulerAngle); + + ModifiedRodriguezParameters(const Quaternion& _qIN); + + // MRP MUTATORS + void Set(const ModifiedRodriguezParameters& _MRP); + + void Set(const double& _s1, const double& _s2, const double& _s3); + + void Set(const Vector& _sVector); + + void Set(const DirectionCosineMatrix& _DCM); + + void Set(const Vector& _EulerAngles, const int& _Sequence); + + void Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); + + void Set(const Vector& _EulerAxis, const Angle& _EulerAngle); + + void Set(const Quaternion& _qIN); + + // MRP INSPECTORS + DirectionCosineMatrix GetDCM() const; + + Vector GetEulerAngles(int _Sequence) const; + + void GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; + + Quaternion GetQuaternion() const; + + // MRP OPERATORS + void Switch(int _SwitchThreshold = 1); + + void AutoSwitch(bool _SwitchBoolean = false); + + ModifiedRodriguezParameters ShadowSet() const; + + ModifiedRodriguezParameters operator+ (const ModifiedRodriguezParameters& _MRP2) const; + + ModifiedRodriguezParameters operator- (const ModifiedRodriguezParameters& _MRP2) const; + // end of MRPOperators +private: + /*! \brief Configuration for auto-switching to shadow set. */ + bool m_AutoSwitch; +}; +// end of ModifiedRodriguezParameters + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \brief The non-singular, redundant Euler parameter (quaternion) vector. +* \ingroup RotationLibrary +* +* +The 4-element quaternion set, \f${\bf{\bar q}}\f$ contains no +singularities similar to those found in an Euler angle set. The +quaternion, \f$\bar{\bf q}=[{\bf q}^{T}, q_{4}]^{T}\f$, can be determined from the Euler-axis parameters set +(\f$\hat{\bf e}\f$, \f$\Phi \f$) as follows: +\f[{\bf{q}} = \hat{\bf e}\sin \frac{\Phi}{2}\f] +\f[q_4 = \cos \frac{\Phi }{2}\f] +The quaternion representation has the useful characteristic that it should have unit length. Therefore, the quaternion can be normalized during computations to help accuracy, \f$\bar{\bf q}_{new}=\frac{\bar{\bf q}}{|\bar{\bf q}|}\f$. Also, the quaternion is not unique, but can also equal its negative \f$\bar{\bf q}=-\bar{\bf q}\f$. +*/ +class Quaternion:public Vector +{ +public: + // QUATERNION CONSTRUCTORS + Quaternion(); + + Quaternion(double _q1, double _q2, double _q3, double _q4); + +// Quaternion(const Matrix& _qMatrix); + + Quaternion(const Vector& _qVector); + + Quaternion(const DirectionCosineMatrix& _DCM); + + Quaternion(const Vector& _EulerAngles, const int& _Sequence); + + Quaternion(const Vector& _EulerAxis, const Angle& _EulerAngle); + + Quaternion(const ModifiedRodriguezParameters& _MRP); + + // QUATERNION MUTATORS + void Set(const Quaternion& _qIn); + + void Set(double _q1, double _q2, double _q3, double _q4); + +// void Set(const Matrix& _qMatrix); + + void Set(const Vector& _qVector); + + void Set(const DirectionCosineMatrix& _DCM); + + void Set(const Vector& _EulerAngles, const int& _Sequence); + + void Set(const Vector& _EulerAxis, const Angle& _EulerAngle); + + void Set(const ModifiedRodriguezParameters& _MRP); + + // QUATERNION INSPECTORS + DirectionCosineMatrix GetDCM() const; + + Vector GetEulerAngles(const int& _Sequence) const; + + Vector GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; + + Vector GetEulerAxisAngle() const; + + ModifiedRodriguezParameters GetMRP() const; + + // QUATERNION OPERATORS + void Normalize(); + + Quaternion operator+ (const Quaternion& _quat2) const; + + Quaternion operator- (const Quaternion& _quat2) const; + +private: + +}; +// end of Quaternion + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \brief A generalized rotation class to represent any attitude coordinate transformation. +* \ingroup RotationLibrary +* \todo Write description of rotation class. +* +* +\par Examples: +It is very easy to setup and output rotations. Note that to output a rotation you must first choose what attitude state to represent it in (you cannot "cout << MyRotation" directly: + +\code +Rotation rotOB; +rotOB.Set(deg2rad(40),deg2rad(-10),deg2rad(0), 321); \\ setup a 321 rotation of euler angles with [40, -10, 0] deg +cout << rotOB.GetDCM(); +\endcode + +Successive Rotations: +\code +Rotation rotOB(quatOB); // create a rotation given the quaternion from Body to Orbital +Rotation rotIO(quatIO); // create a rotation given the quaternion from Orbital to Inertial +Rotation rotIB; +rotIB = rotIO * rotOB; // the successive rotation can be calculate by 'multiplying' the rotations +rotIB = rotIO + rotOB; // or by 'adding' them +\endcode +* +* Inverse Transformation: +\code +Rotation rotBI; +rotBI = ~rotIB; // determine the transformation from Inertial to Body from the inverse (transpose) of Body to Inertial +\endcode +* +* Relative Rotation: +\code +Rotation rotError; +rotError = rotTrue - rotActual; // determine the error rotation by taking the 'difference' between the two respective rotations +\endcode +* +*/ +class Rotation +{ +public: + // ROTATION CONSTRUCTORS + Rotation(); + + Rotation(const Matrix& _inMatrix); + + Rotation(const DirectionCosineMatrix& _DCM); + + Rotation(const Vector& _Angles, const int& _Sequence); + + Rotation(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); + + Rotation(const Vector& _Axis, const Angle& _Angle); + + Rotation(const ModifiedRodriguezParameters& _MRP); + + Rotation(const Quaternion& _quat); + + virtual ~Rotation(); + + // ROTATION MUTATORS + void Set(const Matrix& _inMatrix); + + void Set(const DirectionCosineMatrix& _DCM); + + void Set(const Vector& _Angles, const int& _Sequence); + + void Set(const Angle& _Angle1, const Angle& _Angle2, const Angle& _Angle3, const int& _Sequence); + + void Set(const Vector& _Axis, const Angle& _Angle); + + void Set(const ModifiedRodriguezParameters& _MRP); + + void Set(const Quaternion& _quat); + + // end of RotationMutators + + // ROTATION INSPECTORS + DirectionCosineMatrix GetDCM() const; + + Vector GetEulerAngles(const int& _Sequence) const; + + Vector GetEulerAxisAngle(Vector& _EulerAxis, Angle& _EulerAngle) const; + + Vector GetEulerAxisAngle() const; + + ModifiedRodriguezParameters GetMRP() const; + + Quaternion GetQuaternion() const; + + Vector GetRotation(const RotationType& _type, const int& _Sequence = 123) const; + + // ROTATION OPERATORS + Rotation Rotation::operator* (const Rotation& _rot2) const; + + Vector Rotation::operator* (const Vector& _vec) const; + + Rotation Rotation::operator~ () const; + + Rotation Rotation::operator+ (const Rotation& _rot2) const; + + Rotation Rotation::operator- (const Rotation& _rot2) const; + // end of RotationOperators + +private: + /*! \brief internal representation of the attitude transformation.*/ + Quaternion m_quaternion; + + /*! \brief Handed-ness of the rotation, either LEFT_HANDED or RIGHT_HANDED */ + RotationSense m_RotationSense; + +}; +} + +#endif +/*!*************************************************************************** +* $Log: Rotation.h,v $ +* Revision 1.19 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.18 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.17 2003/05/22 03:03:38 nilspace +* Update documentation, and changed all angles to use Angle type. +* +* Revision 1.16 2003/05/21 22:18:05 nilspace +* Moved the documentation to the implementation file. +* +* Revision 1.15 2003/05/20 17:53:51 nilspace +* Updated comments. +* +* Revision 1.14 2003/05/13 19:45:10 nilspace +* Updated comments. +* +* Revision 1.13 2003/04/28 14:16:26 nilspace +* Moved all function definitions out of header file into implementation file. +* +* Revision 1.12 2003/04/27 20:41:10 nilspace +* Encapsulated the rotation library into the namespace O_SESSAME. +* +* Revision 1.11 2003/04/23 14:56:18 simpliciter +* Clarified comments on quaternions (automatic normalization) and +* outputting rotations (can't do it). +* +* Revision 1.10 2003/04/22 21:59:58 nilspace +* Fixed Quaternion::Set(DCM) so it evaluates correctly. +* Implemented Rotation::operator-() +* +* Revision 1.9 2003/04/22 19:36:03 nilspace +* Various bug fixes to DCM & quaternion conversions. Added DirectionCosineMatrix Normalize(). +* +* Revision 1.8 2003/04/22 16:03:11 nilspace +* Updated MRP::Set(Quaternion) to correctly set. +* +* Revision 1.7 2003/04/10 17:25:52 nilspace +* changelog +* +* Revision 1.6 2003/04/08 23:02:27 nilspace +* Added Rotation Sense, or "Handedness". Defaults to RIGHT_HAND +* +* Revision 1.5 2003/03/27 20:22:27 nilspace +* Added GetRotation() function. +* Fixed Quaternion.Set(Quaternion) function. +* Added RotationType enum. +* Made sure to normalize the Quaternions for all the Set() functions. +* +* Revision 1.4 2003/03/25 02:37:36 nilspace +* Added quaternion matrix set and constructor. +* Added Rotation generalized matrix set to check for quaternion. +* +* Revision 1.3 2003/03/04 17:36:20 nilspace +* Added CVS tags for documenting uploads. Also chmod'd to not be executable. +* +* Revision 1.1 2003/02/27 18:37:26 nilspace +* Initial submission of Attitude class implementation. +* +* +******************************************************************************/ diff --git a/src/rotation/rotation.pro b/src/rotation/rotation.pro new file mode 100644 index 0000000..c69f4e9 --- /dev/null +++ b/src/rotation/rotation.pro @@ -0,0 +1,24 @@ +# +# $Id: rotation.pro,v 1.7 2003/10/18 21:37:28 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = Rotation.h #Matrix.h +SOURCES = Rotation.cpp +TARGET = osessame_rotation +VERSION = 1.0 + +INCLUDEPATH = .. ../matrix +DESTDIR = ../../lib/ +CONFIG = staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../attitude ../orbit \ + ../datahandling ../dynamics \ + ../environment ../utils diff --git a/src/test/AttitudeSimulatorServer.cpp b/src/test/AttitudeSimulatorServer.cpp new file mode 100644 index 0000000..94b4df7 --- /dev/null +++ b/src/test/AttitudeSimulatorServer.cpp @@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file HokiesatAttitudeSim.cpp +* \brief Implementation of a HokieSat Attitude Simulation using the Open-SESSAME Framework. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/08/24 20:59:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +#include "Matrix.h" +#include "RungeKuttaIntegrator.h" +#include "AttitudeState.h" +#include +using namespace std; + +#include "SSFComm.h" + + + +Vector ControlTorques(Matrix CurrentAttState, Matrix DesAttState, double epoch, double count) // HYK +{ + /* This function takes the current and desired attitudes (orbital to body) + * and returns the needed control torque (in N-m) + */ + static Matrix Kp(3,3); // gain on quaternion + static Matrix Kd(3,3); // gain on angular velocity + static Matrix qCurrent(4,1); // current quaternion (orbital to body) + static Matrix qDesired(4,1); // desired quaternion (orbital to body) + static Matrix wCurrent(3,1); // current angular velocity (orbital to body, rad/s) + static Matrix wDesired(3,1); // desired angular velocity (orbital to body, rad/s) + static Matrix qError(4,1); // the error quaternion (desired to body) + static Matrix qErrAxis(3,1); // Euler axis for desired to body rotation + static double qError4; // fourth entry of error quaternion + static Matrix wError; // Angular Velocity error + static Matrix sigma(3,1); // scaled error quaternion + + static Matrix Inertia(3,3); // Moments of inertia, kg-m^2 + + + + qCurrent = CurrentAttState[mslice(0,0,4,1)]; + qDesired = DesAttState[mslice(0,0,4,1)]; //HYKIM Oct 15 + wCurrent = CurrentAttState[mslice(4,0,3,1)]; + wDesired = DesAttState[mslice(4,0,3,1)]; + + qError = ATT_qMult(qCurrent, qDesired); + + wError = wCurrent - wDesired; + qErrAxis = qError[mslice(0,0,3,1)]; + qError4 = qError(3,0); + + Kd = .02*eye(3); + Kp = 0.0006*eye(3); + + Matrix Torque_r(3,1); + /* smaller torque */ + // Kd = .05*eye(3); + // Kp = 0.0005*eye(3); + + sigma = qErrAxis / (1 + qError4); + Torque_r = -Kp * sigma* (eye(1) + ~sigma * sigma) - Kd * wError; + + Matrix B(3,1); + B = ATT1_CalcG(epoch, count); // HYK + //B = B / B.norm2(); + //Torque = Torque_r - (~Torque_r*B)*B; + Matrix K(3,6); + + K(1,1) = 0.040424; K(1,2) = 0.000065; K(1,3) = 0.000110; K(1,3) = 30.393883; K(1,4) = -0.671557; K(1,5) = -0.233840; + K(2,1) = -0.000724; K(2,2) = 0.030161; K(2,3) = -0.022378; K(2,3) = -1.024919; K(2,4) = 34.678584; K(2,5) = -10.027221; + K(3,1) = -0.000370; K(3,2) = 0.020404; K(3,3) = 0.019692; K(3,3) = -0.326869; K(3,4) = -1.073717; K(3,5) = 24.430588; + + Matrix dx(6,1), gm(6,1), Gt(6,3); + + + + dx[mslice(0,0,3,1)] = qErrAxis; + dx[mslice(3,0,3,1)] = wError; + + Matrix Rto(3,3), qbt(4,1), wbt(3,1) ; + Matrix temp5(3,1); + Rto = ATT_q2R(qDesired); + qbt = ATT_itzhackR2q(ATT_q2R(qCurrent)*~Rto); + + temp5= qbt[mslice(0,0,3,1)]; + //cout<<"up="< 0) + { + // Set the final integration time to the requested time + integrationTimes[1] = simTimeData.simTime; + + cout << "PropTime = " << integrationTimes[0].GetSeconds() << " s -> " << integrationTimes[1].GetSeconds() << " s" << endl; + + // Integrate over the desired time interval + Matrix history = myIntegrator.Integrate( + integrationTimes, // seconds + &AttituteDynamics, + myAttitude.GetState(), + myOrbit, + myAttitude, + MOI, + AttitudeForcesFunctor + ); + // on the next pass, the specified time will be the beginning time + integrationTimes[0] = simTimeData.simTime; + attitudeState.time = simTimeData.simTime.GetSeconds(); + attitudeState.q1 = (myAttitude.GetState())(1); + attitudeState.q2 = (myAttitude.GetState())(2); + attitudeState.q3 = (myAttitude.GetState())(3); + attitudeState.q4 = (myAttitude.GetState())(4); + attitudeState.w1 = (myAttitude.GetState())(5); + attitudeState.w2 = (myAttitude.GetState())(6); + attitudeState.w3 = (myAttitude.GetState())(7); + + // write out to pipe + client_fifo_fd = open(client_fifo, O_WRONLY); + if(client_fifo_fd != -1) + { + cout << "sending : " << attitudeState.time << " [ " << attitudeState.q1 << ", " + << attitudeState.q2 << ", " + << attitudeState.q3 << ", " + << attitudeState.q4 << " : " + << attitudeState.w1 << ", " + << attitudeState.w2 << ", " + << attitudeState.w3 << " ]" << endl; + write(client_fifo_fd, &attitudeState, sizeof(attitudeState)); + close(client_fifo_fd); + } + else + cout << "Could not open Client FIFO FD" << endl; + } + else + { + cout << "Server has nothing to read." << endl; + ++ii; + } + } + cout << "Closing Attitude Server" << endl; + close(server_fifo_fd); + unlink (SERVER_FIFO_NAME); + exit(EXIT_SUCCESS); + + + return 0; + +} + +void DeviceRun() +{ + sleep(2); + cout << "Running Device Model" << endl; + SetupSSFComm(); + for (int ii = 0; ii < 5; ++ii) + { + cout << "Run " << ii << ": " << endl; + SSFGetAttitude(); + } + StopSSFComm(); +} + +// Starts up the processes +int main() +{ + pid_t new_pid; + new_pid = fork(); + switch(new_pid) + { + case 0 : // child + cout << "Running Attitude Server" << endl; + AttitudeServer(); + break; + + default : // parent + DeviceRun(); + break; + } + + return 0; + +} + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: AttitudeSimulatorServer.cpp,v $ +* Revision 1.2 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.1 2003/05/01 15:29:59 nilspace +* First commit. +* +* +******************************************************************************/ + + + diff --git a/src/test/CVS/Entries b/src/test/CVS/Entries new file mode 100644 index 0000000..6690db9 --- /dev/null +++ b/src/test/CVS/Entries @@ -0,0 +1,14 @@ +/AttitudeSimulatorServer.cpp/1.2/Sun Aug 24 20:59:13 2003// +/HokieSatSimulation.cpp/1.5/Sun Aug 24 20:59:13 2003// +/HokieSatSimulation.h/1.3/Sun Aug 24 20:59:13 2003// +/Makefile/1.13/Fri Jul 14 02:51:45 2006// +/testAttitudeIntegration.cpp/1.6/Sun Aug 24 20:59:13 2003// +/testDynamics.cpp/1.4/Thu Jun 30 11:24:18 2005// +/testEnvironment.cpp/1.2/Sun Aug 24 20:59:13 2003// +/testIntegration.cpp/1.3/Thu Jun 30 10:58:10 2005// +/testInterface.cpp/1.5/Sat Oct 18 13:58:02 2003// +/testMatrix.cpp/1.3/Tue Jun 17 19:53:18 2003// +/testOrbitIntegration.cpp/1.4/Sun Aug 24 20:59:13 2003// +/testPropagation.cpp/1.4/Tue May 27 17:47:13 2003// +/testRotation.cpp/1.4/Sun Aug 24 20:59:13 2003// +D diff --git a/src/test/CVS/Repository b/src/test/CVS/Repository new file mode 100644 index 0000000..86e87f5 --- /dev/null +++ b/src/test/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/test diff --git a/src/test/CVS/Root b/src/test/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/test/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/test/HokieSatSimulation.cpp b/src/test/HokieSatSimulation.cpp new file mode 100644 index 0000000..ef66c0f --- /dev/null +++ b/src/test/HokieSatSimulation.cpp @@ -0,0 +1,339 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file HokieSatSimulation.cpp +* \brief Demonstrates the use of Open-SESSAME for simulating HokieSat. +* \author $Author: nilspace $ +* \version $Revision: 1.5 $ +* \date $Date: 2003/08/24 20:59:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/*! +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "HokieSatSimulation.h" + +/** @brief Main operating function for HokieSat simulation. +* @author Andrew Turner +* +* Breaks down all object initializations into seperate functions. +*/ +int main() +{ + Orbit* pHokiesatOrbit = SetupOrbit(); + Attitude* pHokiesatAttitude = SetupAttitude(); + + // Setup Propagator + NumericPropagator* pHokiesatPropagator = SetupPropagator(); + pHokiesatOrbit->SetPropagator(pHokiesatPropagator); + pHokiesatAttitude->SetPropagator(pHokiesatPropagator); + + // Setup external environment + Environment* pEarthEnv = SetupEnvironment(pHokiesatAttitude); + pHokiesatOrbit->SetEnvironment(pEarthEnv); + pHokiesatAttitude->SetEnvironment(pEarthEnv); + + // Integration Times + double propTime = 20; // mins + cout << "Propagation time (mins): " << flush; + cin >> propTime; + double propStep = 60; // s + cout << "Propagation step (secs): " << flush; + cin >> propStep; + vector integrationTimes; + ssfTime begin(0); + ssfTime end(begin + propStep); + integrationTimes.push_back(begin); + integrationTimes.push_back(end); + + // Output the current state properties + cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl; + cout << "Orbit State: " << ~pHokiesatOrbit->GetStateObject().GetStateRepresentation()->GetPositionVelocity(); + cout << "Attitude State: " << ~pHokiesatAttitude->GetStateObject().GetState() << endl; + + // Integrate over the desired time interval + tick(); + pHokiesatPropagator->Propagate(integrationTimes, pHokiesatOrbit->GetStateObject().GetStateRepresentation()->GetPositionVelocity(), pHokiesatAttitude->GetStateObject().GetState()); + + for (int ii = 0; ii < propTime*60/propStep ; ++ii) + { + // Integrate again + integrationTimes[0] = integrationTimes[1]; + integrationTimes[1] = integrationTimes[0] + propStep; + //cout << integrationTimes[0] << " -> " << integrationTimes[1] << endl; + pHokiesatPropagator->Propagate(integrationTimes, pHokiesatOrbit->GetStateObject().GetStateRepresentation()->GetPositionVelocity(), pHokiesatAttitude->GetStateObject().GetState()); + if((ii % 100) < 5) + cout << integrationTimes[0].GetSeconds() << ", "; + } + cout << endl; + ssfSeconds calcTime = tock(); + cout << "finished propagating " << propTime*60 << " sim-seconds in " << calcTime << " real-seconds." << endl; + // Plot the state history + Matrix orbitHistory = pHokiesatOrbit->GetHistoryObject().GetHistory(); + Matrix orbitPlotting = orbitHistory(_,_(MatrixIndexBase+1,MatrixIndexBase+3)); + Matrix attitudeHistory = pHokiesatAttitude->GetHistoryObject().GetHistory(); + Matrix attitudePlotting = attitudeHistory(_,_(MatrixIndexBase,MatrixIndexBase+4)); + + Plot3D(orbitPlotting); + Plot2D(attitudePlotting); + + // Store the output to file + ofstream ofile; + ofile.open("OrbitHistory.dat"); + ofile << pHokiesatOrbit->GetHistoryObject().GetHistory(); + ofile.close(); + + ofile.open("AttitudeHistory.dat"); + ofile << pHokiesatAttitude->GetHistoryObject().GetHistory(); + ofile.close(); + + return 0; + +} + +// ************************* +// ****** ENVIRONMENT ****** +// ************************* +Environment* SetupEnvironment(Attitude* pSatAttitude) +{ + // ENVIRONMENT TESTING + Environment* pEarthEnv = new Environment; + EarthCentralBody *pCBEarth = new EarthCentralBody; + pEarthEnv->SetCentralBody(pCBEarth); + + // Add Gravity force function + EnvFunction TwoBodyGravity(&GravityForceFunction); + double *mu = new double(pCBEarth->GetGravitationalParameter()); + TwoBodyGravity.AddParameter(reinterpret_cast(mu), 1); + pEarthEnv->AddForceFunction(TwoBodyGravity); + + cout << "Add Drag? (y or n): " << flush; + char answer; + cin >> answer; + if(answer == 'y') + { + // Add Drag Force Function + EnvFunction DragForce(&SimpleAerodynamicDragForce); + double *BC = new double(2); + DragForce.AddParameter(reinterpret_cast(BC), 1); + double *rho = new double(1.13 * pow(static_cast(10), static_cast(-12))); // kg/m^3 + DragForce.AddParameter(reinterpret_cast(rho), 2); + pEarthEnv->AddForceFunction(DragForce); + } + // Add Gravity torque function + + EnvFunction GGTorque(&GravityGradientTorque); + Matrix *MOI = new Matrix(pSatAttitude->GetParameters()(_(1,3),_)); + GGTorque.AddParameter(reinterpret_cast(MOI), 1); + GGTorque.AddParameter(reinterpret_cast(mu), 2); + pEarthEnv->AddTorqueFunction(GGTorque); + + // Assign Magnetic Model + pCBEarth->SetMagneticModel(new TiltedDipoleMagneticModel); + return pEarthEnv; +} + +// ************************* +// ****** PROPAGATOR ******* +// ************************* +NumericPropagator* SetupPropagator() +{ + CombinedNumericPropagator* pSatProp = new CombinedNumericPropagator; + + // Create & setup the integator + // Setup an integrator and any special parameters + RungeKuttaFehlbergIntegrator* orbitIntegrator = new RungeKuttaFehlbergIntegrator; + RungeKuttaFehlbergIntegrator* attitudeIntegrator = new RungeKuttaFehlbergIntegrator; + + orbitIntegrator->SetTolerance(pow(10.,-7.)); + orbitIntegrator->SetStepSizes(0.01, 300); + pSatProp->SetOrbitIntegrator(orbitIntegrator); + attitudeIntegrator->SetTolerance(pow(10.,-7.)); + attitudeIntegrator->SetStepSizes(0.01, 5); + pSatProp->SetAttitudeIntegrator(attitudeIntegrator); + + return pSatProp; +} + +// ************************* +// ********* ORBIT ********* +// ************************* +Orbit* SetupOrbit() +{ + Orbit* pSatOrbit = new Orbit; + + // Create & initialize the orbit + OrbitState SatOrbitState; + SatOrbitState.SetStateRepresentation(new PositionVelocity); + SatOrbitState.SetOrbitFrame(new OrbitFrameIJK); + Vector initPV(6); + // Space station + initPV(VectorIndexBase+0) = -5776.6; // km + initPV(VectorIndexBase+1) = -157; // km + initPV(VectorIndexBase+2) = 3496.9; // km + initPV(VectorIndexBase+3) = -2.595; // km/s + initPV(VectorIndexBase+4) = -5.651; // km/s + initPV(VectorIndexBase+5) = -4.513; // km/s + SatOrbitState.SetState(initPV); + pSatOrbit->SetStateObject(SatOrbitState); + + pSatOrbit->SetDynamicsEq(&TwoBodyDynamics); + pSatOrbit->SetStateConversion(&PositionVelocityConvFunc); + + return pSatOrbit; +} + + +// ************************* +// ******* ATTITUDE ******** +// ************************* +Attitude* SetupAttitude() +{ + Attitude* pSatAttitude = new Attitude; + + AttitudeState SatAttState; + SatAttState.SetRotation(Rotation(Quaternion(0,0,0,1))); + Vector initAngVelVector(3); + initAngVelVector(1) = 0; + SatAttState.SetAngularVelocity(initAngVelVector); + + pSatAttitude->SetStateObject(SatAttState); + pSatAttitude->SetDynamicsEq(&AttituteDynamics_QuaternionAngVel); + pSatAttitude->SetStateConversion(&QuaternionAngVelConvFunc); + + // Create the matrix of parameters needed for the RHS + Matrix MOI(3,3); + MOI(1,1) = 0.4084; MOI(1,2) = 0.0046; MOI(1,3) = 0.0; + MOI(2,1) = 0.0046; MOI(2,2) = 0.3802; MOI(2,3) = 0.0; + MOI(3,1) = 0.0; MOI(3,2) = 0.0; MOI(3,3) = 0.4530; + + MOI = eye(3); + MOI(1,1) = 2; MOI(2,2) = 2; MOI(3,3) = 10; + Matrix params(6,3); + params(_(1,3),_) = MOI; + params(_(4,6),_) = MOI.inverse(); + + pSatAttitude->SetParameters(params); + + return pSatAttitude; + +} + +Vector ControlTorques(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) // HYK +{ + /* This function takes the current and desired attitudes (orbital to body) + * and returns the needed control torque (in N-m) + */ + /* + static Matrix Kp(3,3); // gain on quaternion + static Matrix Kd(3,3); // gain on angular velocity + static Matrix qCurrent(4,1); // current quaternion (orbital to body) + static Matrix qDesired(4,1); // desired quaternion (orbital to body) + static Matrix wCurrent(3,1); // current angular velocity (orbital to body, rad/s) + static Matrix wDesired(3,1); // desired angular velocity (orbital to body, rad/s) + static Matrix qError(4,1); // the error quaternion (desired to body) + static Matrix qErrAxis(3,1); // Euler axis for desired to body rotation + static double qError4; // fourth entry of error quaternion + static Matrix wError; // Angular Velocity error + static Matrix sigma(3,1); // scaled error quaternion + + static Matrix Inertia(3,3); // Moments of inertia, kg-m^2 + + + + qCurrent = CurrentAttState[mslice(0,0,4,1)]; + qDesired = DesAttState[mslice(0,0,4,1)]; //HYKIM Oct 15 + wCurrent = CurrentAttState[mslice(4,0,3,1)]; + wDesired = DesAttState[mslice(4,0,3,1)]; + + qError = ATT_qMult(qCurrent, qDesired); + + wError = wCurrent - wDesired; + qErrAxis = qError[mslice(0,0,3,1)]; + qError4 = qError(3,0); + + Kd = .02*eye(3); + Kp = 0.0006*eye(3); + + Matrix Torque_r(3,1); + + + sigma = qErrAxis / (1 + qError4); + Torque_r = -Kp * sigma* (eye(1) + ~sigma * sigma) - Kd * wError; + + Matrix B(3,1); + B = ATT1_CalcG(epoch, count); // HYK + //B = B / B.norm2(); + //Torque = Torque_r - (~Torque_r*B)*B; + Matrix K(3,6); + + K(1,1) = 0.040424; K(1,2) = 0.000065; K(1,3) = 0.000110; K(1,3) = 30.393883; K(1,4) = -0.671557; K(1,5) = -0.233840; + K(2,1) = -0.000724; K(2,2) = 0.030161; K(2,3) = -0.022378; K(2,3) = -1.024919; K(2,4) = 34.678584; K(2,5) = -10.027221; + K(3,1) = -0.000370; K(3,2) = 0.020404; K(3,3) = 0.019692; K(3,3) = -0.326869; K(3,4) = -1.073717; K(3,5) = 24.430588; + + Matrix dx(6,1), gm(6,1), Gt(6,3); + + + + dx[mslice(0,0,3,1)] = qErrAxis; + dx[mslice(3,0,3,1)] = wError; + + Matrix Rto(3,3), qbt(4,1), wbt(3,1) ; + Matrix temp5(3,1); + Rto = ATT_q2R(qDesired); + qbt = ATT_itzhackR2q(ATT_q2R(qCurrent)*~Rto); + + temp5= qbt[mslice(0,0,3,1)]; + //cout<<"up="< +using namespace std; + + +// Torque function that will be called each timestep +Vector NullFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState) +{ + return Vector(3); +} +/* +static Vector EugeneDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + //function statedot=test1_rhs(t,state) + static Vector h = _integratingState(_(1,3)); //h=state(1:3); + static double T = _integratingState(4); //T=state(4); + + Matrix I(3,3); //I=[100 0 0;0 200 0;0 0 150]; + I(1,1) = 100; + I(2,2) = 200; + I(3,3) = 150; + static Vector w = I.inverse() * h; //w=inv(I)*h; + Vector ge(3); //ge=[0 0 0]'; + + static Vector hdot = skew(w) * h + ge; //hdot=-cr(w)*h+ge; + static Vector wdot = I.inverse() * hdot; //wdot=inv(I)*hdot; + static Matrix temp = (~ge * wdot); //Tdot=ge'*wdot; + double Tdot = temp(1,1); + + static Vector statedot(hdot.getIndexBound() + 1); + statedot(_(1, hdot.getIndexBound())) = hdot(_); + statedot(hdot.getIndexBound()+1) = Tdot; + + return statedot; //statedot=[hdot; Tdot]; + +}*/ + +/*! \brief Dynamic and Kinematic attitude equations using quaternion and angular velocities. +*/ +static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + // Initialize the vectors used in the calculation. + // made static, which causes the memory to be allocated the first time the function is called + // and then left in memory during the program to speed up computation. + static Vector stateDot(7); + static Matrix bMOI(3,3); + static Matrix qtemp(4,3); + static Matrix Tmoment(3,1); + static Vector qIn(4); + static Vector wIn(3); + + // Retrieve the current integration states to a quaternion and angular velocity vector + qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3)); + wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6)); + qIn /= norm2(qIn); + + // Calculate qDot + qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3); + qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2))); + qtemp(_,MatrixIndexBase) = 0.5 * qtemp * wIn; + + // Get the moments of inertia and calculate the omegaDot + bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2)); + Tmoment = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn))); + + // Combine the qDot and omegaDot into a stateDot vector + stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = qtemp(_,MatrixIndexBase); + stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = Tmoment(_,MatrixIndexBase); + + cout << 0.5 * ~wIn * (bMOI * wIn); + return stateDot; +} + +int main() +{ + ////////////////////////////////////////////////// + // Setup an integrator and any special parameters + RungeKuttaIntegrator myIntegrator; + myIntegrator.SetNumSteps(1000); + // Integration times + vector integrationTimes; + ssfTime begin(0); + ssfTime end(begin + 20); + integrationTimes.push_back(begin); + integrationTimes.push_back(end); + + // Create the initial attitude state + AttitudeState myAttitudeState; + myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1))); + Vector initAngVelVector(3); + initAngVelVector(1) = 0.1; + myAttitudeState.SetAngularVelocity(initAngVelVector); + SpecificFunctor AttitudeForcesFunctor(&NullFunctor); + + // Create the matrix of parameters needed for the RHS - MOI + Matrix Parameters = eye(3); + + Matrix I(3,3); //I=[100 0 0;0 200 0;0 0 150]; + I(1,1) = 100; + I(2,2) = 200; + I(3,3) = 150; + Vector h(3); + h(1) = 10; + h(2) = 20; + h(3) = 30; + + Vector w = I.inverse() * h; + Matrix Tmat = 0.5 * (~w * (I * w)); + Vector initEugeneState(4); + initEugeneState(_(1,3)) = h(_(1,3)); + initEugeneState(4) = Tmat(1,1); + + + cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl; + cout << "Attitude State: " << ~myAttitudeState.GetState() << endl; + /////////////////////////////////////////////// + // Integrate over the desired time interval + tick(); + Matrix history = myIntegrator.Integrate( + integrationTimes, // seconds + &AttituteDynamics, + myAttitudeState.GetState(), + NULL, + NULL, + Parameters, + AttitudeForcesFunctor + ); + + cout << "finished propagating in " << tock() << " seconds." << endl; + // Output the flight history + //cout << history; + Matrix plotting = history(_,_(MatrixIndexBase,MatrixIndexBase+4)); + +// Plot2D(plotting); + + /////////////////////////////////////////////// + // Create & populate an AttitudeHistory object + AttitudeHistory myAttHistory; + myAttHistory.SetInterpolator(new LinearInterpolator); + Vector AngVel(3); + Vector Quat(4); + Rotation myRot; + for(int jj = 1;jj <= history[MatrixRowsIndex].getIndexBound(); ++jj) + { + AngVel = ~(history(jj, _(6,8))); + Quat = ~(history(jj,_(2,5))); + myRot.Set(Quaternion(Quat)); + myAttHistory.AppendHistory(history(jj,1), myRot, AngVel); + } + + ///////////////////////////////////////////////// + // Output the attitude state at a requested time + double requestTime; + cout << "Output attitude state at time (s): " << flush; + cin >> requestTime; + ssfTime myTime(requestTime); + myAttHistory.GetState(myTime, myRot, AngVel); + cout << myTime.GetSeconds() << " : " << ~myRot.GetQuaternion() << endl; + + /* + // Verifying the energy + Matrix calcHistory = history; + for(int ii = 1; ii <= history[MatrixRowsIndex].getIndexBound(); ++ii) + { + h = ~(history(ii,_(2,4))); + w = I.inverse() * h; + Tmat = 0.5 * (~w * (I * w)); + calcHistory(ii,5) = Tmat(1,1); + } + Plot2D(calcHistory);*/ + + ///////////////////////////////////////////////// + // Store the output to file + ofstream ofile; + ofile.open("AttitudeHistory.dat"); + ofile << history; + ofile.close(); + + return 0; + +} +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testAttitudeIntegration.cpp,v $ +* Revision 1.6 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.5 2003/05/22 14:48:11 nilspace +* It works, for now. Changed so integrator just takes NULL pointers to Attitude & Orbit. +* +* Revision 1.4 2003/05/22 03:02:52 nilspace +* Pass pointers to Orbit & Attitude in integrator (pointers to NULL). +* +* Revision 1.3 2003/05/19 19:19:55 nilspace +* Updated to include Eugene's "test case". Also made the RHS dynamic equation variables declared as static. +* +* Revision 1.2 2003/05/13 18:55:50 nilspace +* Fixed to work with the new integrator, eugene's functions, History, and interpolation. +* +* Revision 1.1 2003/05/10 01:53:37 nilspace +* Initial submission. Works, but needs to be refined. +* +* +******************************************************************************/ + + diff --git a/src/test/testDynamics.cpp b/src/test/testDynamics.cpp new file mode 100644 index 0000000..d367ddb --- /dev/null +++ b/src/test/testDynamics.cpp @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file testDynamics.cpp +* \brief Test program for trying out rigid body dynamics. +* \author $Author: nilspace $ +* \version $Revision: 1.4 $ +* \date $Date: 2005/06/30 11:24:18 $ +////////////////////////////////////////////////////////////////////////////////////////////////// +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "rotation/Rotation.h" +#include "dynamics/QuaternionDynamics.h" +#include "kinematics/QuaternionKinematics.h" +#include "attitude/Attitude.h" +#include "environment/Environment.h" +#include "environment/CentralBody/EarthCentralBody.h" +#include "environment/Disturbances/GravityFunctions.h" +//#include "utils/Units.h" + +Environment* SetupEnvironment(Attitude &_SpacecraftAttitude) +{ + Environment *pEarthEnv = new Environment; + EarthCentralBody *pCBEarth = new EarthCentralBody; + pEarthEnv->SetCentralBody(pCBEarth); + EnvFunction GGTorque(GravityGradientTorque); + cout << "Filling Parameters" << endl; + GGTorque.AddParameter((void*)&(_SpacecraftAttitude.GetAttitude()), 1); + GGTorque.AddParameter((void*)&(_SpacecraftAttitude.GetMOI()), 2); + GGTorque.AddParameter((void*)&(pCBEarth->GetWc(500000)),3); + pEarthEnv->AddTorqueFunction(GGTorque); + return pEarthEnv; +} + +int main() +{ + Attitude testAttitude; + Rotation rotInit(Quaternion(0.01,0,0,.8)); + + testAttitude.SetAttitude(rotInit); + Vector AngularVelocity(3); + Vector ControlTorques(3); + AngularVelocity(VectorIndexBase) = 0.1; + ControlTorques(VectorIndexBase) = 0.0; + + Matrix MOI = eye(3); + Vector time(2); + time(VectorIndexBase + 0) = 0; + time(VectorIndexBase + 2) = 100; + + // End user specified parameters + testAttitude.SetAngularVelocity(AngularVelocity); + testAttitude.SetControlTorques(ControlTorques); + testAttitude.SetMOI(MOI); + + testAttitude.SetKinematicsEq(&QuaternionKinematics); + testAttitude.SetDynamicsEq(&QuaternionDynamics); + Environment* pEarth = SetupEnvironment(testAttitude); + testAttitude.SetEnvironment(pEarth); +/* + cout << ~testAttitude.GetAttitude().GetRotation(Quaternion_Type) << endl; + cout << ~testAttitude.GetAttitude().GetRotation(DCM_Type) << endl; + cout << ~testAttitude.GetAttitude().GetRotation(EulerAngle_Type) << endl; + cout << ~testAttitude.GetAttitude().GetRotation(EulerAxisAngle_Type) << endl; +*/ + cout << "Propagating..." << endl; + testAttitude.Propagate(time); + + cout << "History: "<< endl << testAttitude.GetHistory(); + + delete pEarth; + return 0; +} + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testDynamics.cpp,v $ +* Revision 1.4 2005/06/30 11:24:18 nilspace +* Fixed some of the include file names - still several errors due to function name changes. +* +* Revision 1.3 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.2 2003/03/27 02:47:29 nilspace +* Updated to propagate a satellite forward for 10 seconds and return the history. +* +* Revision 1.1 2003/03/25 02:26:00 nilspace +* initial submission of test files. +* +* +* +******************************************************************************/ diff --git a/src/test/testEnvironment.cpp b/src/test/testEnvironment.cpp new file mode 100644 index 0000000..54fb4b9 --- /dev/null +++ b/src/test/testEnvironment.cpp @@ -0,0 +1,136 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file testEnvironment.cpp +* \brief Sample of an orbit integration and an Environment object using components of the SSF. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/08/24 20:59:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// +#include "orbitmodels/TwoBodyDynamics.h" +#include "Matrix.h" +#include "RungeKuttaIntegrator.h" +#include "PositionVelocity.h" +#include "Plot.h" +#include "Environment.h" +#include "OrbitStateRepresentation.h" +#include "EarthCentralBody.h" +#include "OrbitState.h" +#include "orbitframes/OrbitFrameIJK.h" + +// Force function that will be called each timestep +Vector GravityForceFunction(ssfTime* _currentTime, OrbitState* _currentOrbitState, AttitudeState* _currentAttitudeState, EnvFuncParamaterType _parameterList) +{ + Vector state = _currentOrbitState->GetState(); + Vector Forces(3); + Vector Position(3); Position(_) = state(_(VectorIndexBase,VectorIndexBase+2)); + Forces = -398600.441 / pow(norm2(Position),3) * Position; + return Forces; +} + +Vector DragForceFunction(ssfTime* _currentTime, OrbitState* _currentOrbitState, AttitudeState* _currentAttitudeState, EnvFuncParamaterType _parameterList) +{ + Vector Forces(3); + double BC = *(reinterpret_cast(_parameterList[1])); + Vector Vrel(3); Vrel = _currentOrbitState->GetState()(_(VectorIndexBase+3,VectorIndexBase+5)); + double Vrel_mag = norm2(Vrel); + Forces = -1/2 *1 / BC * pow(Vrel_mag,2) * Vrel / Vrel_mag; + return Forces; +} + +int main() +{ + // Setup an integrator and any special parameters + RungeKuttaIntegrator myIntegrator; + int numOrbits = 10; + int numSteps = 100; + + cout << "Number of Orbits: " << flush; + cin >> numOrbits; + cout << "Number of Integration Steps: "<< flush; + cin >> numSteps; + + myIntegrator.SetNumSteps(numSteps); + + // Create & initialize an orbit type + OrbitState myOrbit; + myOrbit.SetStateRepresentation(new PositionVelocity); + myOrbit.SetOrbitFrame(new OrbitFrameIJK); + Vector initPV(6); + initPV(VectorIndexBase+0) = -5776.6; // km/s + initPV(VectorIndexBase+1) = -157; // km/s + initPV(VectorIndexBase+2) = 3496.9; // km/s + initPV(VectorIndexBase+3) = -2.595; // km/s + initPV(VectorIndexBase+4) = -5.651; // km/s + initPV(VectorIndexBase+5) = -4.513; // km/s + myOrbit.SetState(initPV); + + AttitudeState myAttitude; + myAttitude.SetRotation(Rotation(Quaternion(0,0,0,1))); + + // Create the matrix of parameters needed for the RHS + Matrix Parameters(1,1); + Parameters(MatrixIndexBase,MatrixIndexBase) = 398600.441; //km / s^2 + + + // ENVIRONMENT TESTING + Environment* pEarthEnv = new Environment; + EarthCentralBody *pCBEarth = new EarthCentralBody; + pEarthEnv->SetCentralBody(pCBEarth); + cout << "Filling Parameters" << endl; + EnvFunction TwoBodyGravity(&GravityForceFunction); + pEarthEnv->AddForceFunction(TwoBodyGravity); + EnvFunction DragForce(&DragForceFunction); + double BC = 200; + DragForce.AddParameter(reinterpret_cast(&BC), 1); + pEarthEnv->AddForceFunction(DragForce); + cout << "Finished Setting up Earth Environment" << endl; + + + vector integrationTimes; + ssfTime begin(Now()); + ssfTime end(begin + 92*60*numOrbits); + integrationTimes.push_back(begin); + integrationTimes.push_back(end); + cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl; + cout << "Orbit State: " << ~myOrbit.GetState() << endl; + + ObjectFunctor OrbitForcesFunctor(pEarthEnv, &Environment::GetForces); + // Integrate over the desired time interval + tick(); + Matrix history = myIntegrator.Integrate( + integrationTimes, // seconds + &TwoBodyDynamics, + myOrbit.GetState(), + NULL, + NULL, + Parameters, + OrbitForcesFunctor + ); + + cout << "finished propagating in " << tock() << " seconds." << endl; + // Output the flight history + //cout << history; + Matrix plotting = history(_,_(MatrixIndexBase+1,MatrixIndexBase+3)); + + Plot3D(plotting); + delete pEarthEnv; + + return 0; + +} + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testEnvironment.cpp,v $ +* Revision 1.2 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.1 2003/04/08 23:06:26 nilspace +* Initial Submission. +* +* +******************************************************************************/ + + diff --git a/src/test/testIntegration.cpp b/src/test/testIntegration.cpp new file mode 100644 index 0000000..75e8f02 --- /dev/null +++ b/src/test/testIntegration.cpp @@ -0,0 +1,107 @@ +#include "Time.h" +#include "RungeKuttaFehlbergIntegrator.h" +#include "RungeKuttaIntegrator.h" +#include "Matrix.h" +#include + +using namespace std; +using namespace O_SESSAME; +// Torque function that will be called each timestep +Vector NullFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState) +{ + return Vector(3); +} + +Vector testRKFunc(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + static Vector returnVal(1); + returnVal(1) = _integratingState(1) - pow(_time.GetSeconds(),2) + 1; + return returnVal; +} +Vector testRKFunc2(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + static Vector returnVal(1); + returnVal(1) = _integratingState(1) - pow(_time.GetSeconds(),3) + 1; + return returnVal; +} +int main() +{ + ////////////////////////////////////////////////// + // Setup an integrator and any special parameters + RungeKuttaIntegrator myRK4Integrator; + myRK4Integrator.SetNumSteps(10); + + // Integration times + vector integrationTimes; + ssfTime begin(0); + ssfTime end(begin + 2); + integrationTimes.push_back(begin); + integrationTimes.push_back(end); + + SpecificFunctor NothingFunctor(&NullFunctor); + Matrix Parameters(1,1); + + Vector initConditions(1); + initConditions(1) = 0.5; + + ////////////////////////////////////////////////// + // Setup an integrator and any special parameters + RungeKuttaFehlbergIntegrator myRK5Integrator; + myRK5Integrator.SetTolerance(0.0001); + + // Integration times + + /////////////////////////////////////////////// + // Integrate over the desired time interval + tick(); + Matrix RK5History = myRK5Integrator.Integrate( + integrationTimes, // seconds + &testRKFunc, + initConditions, + NULL, + NULL, + Parameters, + NothingFunctor + ); + cout << "finished propagating in " << tock() << " seconds." << endl; + + + + cout << "RK-4(5) output: " << endl << setprecision(15) < +#include +#include +using namespace O_SESSAME; + +// Global Variables +static Orbit* myOrbit = NULL; +static Attitude* myAttitude = NULL; +static Environment* myEnvironment = NULL; +static CombinedNumericPropagator* myPropagator = NULL; +static RungeKuttaFehlbergIntegrator* orbitIntegrator = NULL; +static RungeKuttaFehlbergIntegrator* attitudeIntegrator = NULL; +static vector propTimes; + +void SetupPropagator(); +void SetupEnvironment(); +void SetupOrbit(); +void SetupAttitude(); + +void ChangePropagator(); +void ChangeEnvironment(); +void ChangeOrbit(); +void ChangeOrbitIntegrator(); +void ChangeAttitude(); +void ChangeAttitudeIntegrator(); + +void Propagate(); +void Plot(); + +Vector SimpleController(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList); +void myOrbitStateConvFunc(const Matrix &_meshPoint, OrbitState &_convertedOrbitState); +void myAttitudeStateConvFunc(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState); + +void DisplayOrbit() +{ + if(myOrbit->IsIntegrateable()) + cout << "Orbit State (km, km/s): " << ~myOrbit->GetStateObject().GetStateRepresentation()->GetPositionVelocity() << endl; + else + cout << "Orbit State: [ uninitialized ]" << endl; + return; +} + +void DisplayAttitude() +{ + if(myAttitude->IsIntegrateable()) + cout << "Attitude State: (-, rad/s)" << ~myAttitude->GetStateObject().GetState() << endl; + else + cout << "Attitude State: [ uninitialized ]" << endl; + return; +} +void DisplayPropagator() +{ + if(myPropagator) + cout << "Propagate times: [" << propTimes[0] << " -> " << propTimes[1] << "] (s)" << endl; + else + cout << "Propagate State: [ uninitialized ]" << endl; + return; +} +int DisplayMenu() +{ + DisplayOrbit(); + DisplayAttitude(); + DisplayPropagator(); + cout << endl; + cout << "[1] Setup Orbit" << endl; + cout << "[2] Setup Orbit Integrator" << endl; + cout << "[3] Setup Attitude" << endl; + cout << "[4] Setup Attitude Integrator" << endl; + cout << "[5] Setup Environment" << endl; + cout << "[6] Setup Propagator" << endl; + cout << "[7] Propagate" << endl; + cout << "[8] Plot" << endl; + cout << "[0] Exit" << endl; + cout << endl << "Selection: " << flush; + + int selection; + cin >> selection; + return selection; +} + +void Select() +{ + switch(DisplayMenu()) + { + case 1: // ChangeOrbit + ChangeOrbit(); + break; + case 2: + ChangePropagator(); + //ChangeOrbitIntegrator(); + break; + case 3: + ChangeAttitude(); + break; + case 4: + ChangePropagator(); + //ChangeAttitudeIntegrator(); + break; + case 5: + ChangeEnvironment(); + break; + case 6: + ChangePropagator(); + break; + case 7: + Propagate(); + break; + case 8: + ::Plot(); + break; + case 0: + return; + break; + default: + cout << "Incorrect Selection." << endl; + break; + } + Select(); + +} +int main() +{ + SetupOrbit(); + SetupAttitude(); + SetupPropagator(); + myOrbit->SetPropagator(myPropagator); + myAttitude->SetPropagator(myPropagator); + + SetupEnvironment(); + myOrbit->SetEnvironment(myEnvironment); + myAttitude->SetEnvironment(myEnvironment); + + Select(); + // Store the output to file + ofstream ofile; + + double requestTime; + cout << "Output requested time (s): " << flush; + cin >> requestTime; + + if(myOrbit) + if (myOrbit->IsIntegrateable()) + { + cout << "Orbit State (km, km/s): " << ~myOrbit->GetHistoryObject().GetState(requestTime).GetStateRepresentation()->GetPositionVelocity() << endl; + ofile.open("OrbitHistory.dat"); + ofile << setprecision(15) << myOrbit->GetHistoryObject().GetHistory(); + ofile.close(); + } + + if(myAttitude) + if (myAttitude->IsIntegrateable()) + { + cout << "Attitude State: (-, rad/s)" << ~myAttitude->GetHistoryObject().GetState(requestTime).GetState() << endl; + + ofile.open("AttitudeHistory.dat"); + ofile << setprecision(15) << myAttitude->GetHistoryObject().GetHistory(); + ofile.close(); + } + return 0; + +} + +void Plot() +{ + if(myOrbit) + if (myOrbit->IsIntegrateable()) + { + Matrix orbitHistory = myOrbit->GetHistoryObject().GetHistory(); + Matrix orbitPlotting = orbitHistory(_,_(MatrixIndexBase+1,MatrixIndexBase+3)); + Plot3D(orbitPlotting); + } + if(myAttitude) + if (myAttitude->IsIntegrateable()) + { + Matrix attitudeHistory = myAttitude->GetHistoryObject().GetHistory(); + Matrix attitudePlotting = attitudeHistory(_,_(MatrixIndexBase,MatrixIndexBase+4)); + Plot2D(attitudePlotting); + } + +} + +void Propagate() +{ + + cout << "PropTime = " << propTimes[0].GetSeconds() << " s -> " << propTimes[1].GetSeconds() << " s" << endl; + Vector orbInitState(6); + Vector attInitState(7); + if(myOrbit->IsIntegrateable()) + { + orbInitState = myOrbit->GetStateObject().GetState(); + cout << "Orbit State: " << ~orbInitState << endl; + } + if(myAttitude->IsIntegrateable()) + { + attInitState = myAttitude->GetStateObject().GetState(); + cout << "Attitude State: " << ~attInitState << endl; + } + // Integrate over the desired time interval + tick(); + myPropagator->Propagate(propTimes, orbInitState, attInitState); + ssfSeconds calcTime = tock(); + cout << "finished propagating in " << calcTime << " seconds." << endl; +} +// ************************* +// ****** ENVIRONMENT ****** +// ************************* +void SetupEnvironment() +{ + // ENVIRONMENT TESTING + myEnvironment = new Environment; + EarthCentralBody *pCBEarth = new EarthCentralBody; + myEnvironment->SetCentralBody(pCBEarth); + + return; +} +void ChangeEnvironment() +{ + // Add Gravity force function + cout << "Filling Parameters" << endl; + EnvFunction TwoBodyGravity(&GravityForceFunction); + myEnvironment->AddForceFunction(TwoBodyGravity); + + cout << "Add Drag? (y or n): " << flush; + char answer; + cin >> answer; + if(answer == 'y') + { + // Add Drag Force Function + EnvFunction DragForce(&SimpleAerodynamicDragForce); + double *BC = new double(200); + DragForce.AddParameter(reinterpret_cast(BC), 1); + double *rho = new double(1.13 * pow(static_cast(10), static_cast(-12))); // kg/m^3 + DragForce.AddParameter(reinterpret_cast(rho), 2); + myEnvironment->AddForceFunction(DragForce); + } + cout << "Finished Setting up Earth Environment" << endl; + + // Adds a controller + + EnvFunction Controller(&SimpleController); + Vector* Gains = new Vector(3); + cout << "Input Control gains: "<< flush; + cin >> (*Gains)(1); + cin >> (*Gains)(2); + cin >> (*Gains)(3); + + Controller.AddParameter(reinterpret_cast(Gains),1); + myEnvironment->AddTorqueFunction(Controller); + + return; +} + +// ************************* +// ****** PROPAGATOR ******* +// ************************* +void SetupPropagator() +{ + myPropagator = new CombinedNumericPropagator; + orbitIntegrator = new RungeKuttaFehlbergIntegrator; + attitudeIntegrator = new RungeKuttaFehlbergIntegrator; + + myPropagator->SetOrbitIntegrator(orbitIntegrator); + myPropagator->SetAttitudeIntegrator(attitudeIntegrator); + + // Integration Times + double intTime = 1; + ssfTime begin(0); + ssfTime end(begin + intTime); + propTimes.push_back(begin); + propTimes.push_back(end); + return; +} + +void ChangePropagator() +{ + DisplayPropagator(); + + // Create & setup the integator + // Setup an integrator and any special parameters + int stepSize = 1; + + // Integration Times + double intTime = 1; + cout << "Integration duration (s): " << flush; + cin >> intTime; + /* + cout << "Orbit Integration Stepsize (s): "<< flush; + cin >> stepSize; + orbitIntegrator->SetNumSteps(floor(intTime/stepSize)); + + cout << "Attitude Integration Stepsize(s): "<< flush; + cin >> stepSize; + attitudeIntegrator->SetNumSteps(floor(intTime/stepSize)); + */ + double tolerance; + orbitIntegrator->SetStepSizes(1, 300); + cout << "Orbit Tolerance: " << flush; + cin >> tolerance; + orbitIntegrator->SetTolerance(tolerance); + attitudeIntegrator->SetStepSizes(0.01, 5); + cout << "Attitude Tolerance: " << flush; + cin >> tolerance; + attitudeIntegrator->SetTolerance(tolerance); + ssfTime begin(0); + ssfTime end(begin + intTime); + propTimes[0] = begin; + propTimes[1] = end; +} +// ************************* +// ********* ORBIT ********* +// ************************* +void myOrbitStateConvFunc(const Matrix &_meshPoint, OrbitState &_convertedOrbitState) +{ + static Vector tempVector(_meshPoint[MatrixColsIndex].getIndexBound() - 1); + tempVector(_) = ~_meshPoint(_,_(MatrixIndexBase+1, _meshPoint[MatrixColsIndex].getIndexBound())); + _convertedOrbitState.SetState(tempVector); + return; +} + +void ChangeOrbit() +{ + DisplayOrbit(); + + // Create & initialize the orbit + OrbitState myOrbitState; + myOrbitState.SetStateRepresentation(new PositionVelocity); + myOrbitState.SetOrbitFrame(new OrbitFrameIJK); + Vector initPV(6); + //-5776.6 -157 3496.9 + // -2.595 -5.651 -4.513 + cout << "Enter the position vector (km): " << flush; + cin >> initPV(VectorIndexBase+0); // km + cin >> initPV(VectorIndexBase+1); // km + cin >> initPV(VectorIndexBase+2); // km + cout << "Enter the velocity vector (km): " << flush; + cin >> initPV(VectorIndexBase+3); // km + cin >> initPV(VectorIndexBase+4); // km + cin >> initPV(VectorIndexBase+5); // km + myOrbitState.SetState(initPV); + myOrbit->SetStateObject(myOrbitState); + +// cout << "Choose the dynamics equation: " << flush; + myOrbit->SetDynamicsEq(&TwoBodyDynamics); + myOrbit->SetStateConversion(&myOrbitStateConvFunc); + + // Setup Parameters (ie mass, etc) + return; +} +void SetupOrbit() +{ + myOrbit = new Orbit; + return; +} + + +// ************************* +// ******* ATTITUDE ******** +// ************************* +void myAttitudeStateConvFunc(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState) +{ + static Vector tempQ(4); tempQ(_) = ~_meshPoint(_,_(2, 5)); + static Vector tempVector(3); tempVector(_) = ~_meshPoint(_, _(6, 8)); + _convertedAttitudeState.SetState(Rotation(Quaternion(tempQ)), tempVector); + return; +} +static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + static Vector stateDot(7); + static Matrix bMOI(3,3); + static Matrix qtemp(4,3); + static Vector Tmoment(3); + static Vector qIn(4); + static Vector wIn(3); + + qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3)); + wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6)); + qIn /= norm2(qIn); + + qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3); + qtemp(VectorIndexBase+3, _) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2))); + + bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2)); + Tmoment = _forceFunctorPtr.Call(_time, _Orbit->GetStateObject(), _Attitude->GetStateObject()); + + stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = 0.5 * qtemp * wIn; + stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn))); + + return stateDot; +} + +void ChangeAttitude() +{ + DisplayAttitude(); + double q1,q2,q3,q4; + cout << "Enter Attitude quaternion: " << flush; + cin >> q1 >> q2 >> q3 >> q4; + + AttitudeState myAttitudeState; + myAttitudeState.SetRotation(Rotation(Quaternion(q1,q2,q3,q4))); + + cout << "Enter Attitude angular velocity (rad/s): " << flush; + cin >> q1 >> q2 >> q3; + Vector initAngVelVector(3); + initAngVelVector(1) = q1; + initAngVelVector(2) = q2; + initAngVelVector(3) = q3; + + myAttitudeState.SetAngularVelocity(initAngVelVector); + + myAttitude->SetStateObject(myAttitudeState); + myAttitude->SetDynamicsEq(&AttituteDynamics); + myAttitude->SetStateConversion(&myAttitudeStateConvFunc); + cout << "Enter Principle Moments of Inertia: " << flush; + Matrix MOI = eye(3); + cin >> MOI(1,1); + cin >> MOI(2,2); + cin >> MOI(3,3); + myAttitude->SetParameters(MOI); + + return; +} +void SetupAttitude() +{ + myAttitude = new Attitude; + + return; + +} +Vector SimpleController(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) +{ + static Vector Torques(3); + Torques(1) = (*reinterpret_cast(_parameterList[0]))(1) * sin(_currentTime.GetSeconds()); + Torques(2) = (*reinterpret_cast(_parameterList[0]))(2) * cos(_currentTime.GetSeconds()); + Torques(3) = (*reinterpret_cast(_parameterList[0]))(3); + return Torques; +} +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testInterface.cpp,v $ +* Revision 1.5 2003/10/18 13:58:02 nilspace +* Updated for final testing. +* +* Revision 1.4 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.3 2003/06/05 20:31:54 nilspace +* Changed integrator to Runge-Kutta Fehlberg. +* +* Revision 1.2 2003/05/29 21:12:21 nilspace +* Asks if the user wants to include drag. +* +* Revision 1.1 2003/05/26 21:23:21 nilspace +* Initial submission. +* +* +******************************************************************************/ + + diff --git a/src/test/testMatrix.cpp b/src/test/testMatrix.cpp new file mode 100644 index 0000000..8cc2558 --- /dev/null +++ b/src/test/testMatrix.cpp @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file testDynamics.cpp +* \brief Test program for trying out rigid body dynamics. +* \author $Author: simpliciter $ +* \version $Revision: 1.3 $ +* \date $Date: 2003/06/17 19:53:18 $ +////////////////////////////////////////////////////////////////////////////////////////////////// +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "Matrix.h" +using namespace O_SESSAME; + +int main() +{ + Matrix MOI = eye(3); + cout << "Initialization Finished." << endl; + + cout << MOI << endl; + + Matrix I(3,3); + cout << I << endl; + return 0; +} + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testMatrix.cpp,v $ +* Revision 1.3 2003/06/17 19:53:18 simpliciter +* Added namespace call. +* +* Revision 1.2 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/03/25 02:26:00 nilspace +* initial submission of test files. +* +******************************************************************************/ diff --git a/src/test/testOrbitIntegration.cpp b/src/test/testOrbitIntegration.cpp new file mode 100644 index 0000000..850d674 --- /dev/null +++ b/src/test/testOrbitIntegration.cpp @@ -0,0 +1,164 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file testOrbitIntegration.cpp +* \brief Example of orbit integration using Open-Sessame. +* \author $Author: nilspace $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/08/24 20:59:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/*! +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "orbitmodels/TwoBodyDynamics.h" +#include "Matrix.h" +#include "RungeKuttaFehlbergIntegrator.h" +#include "OrbitState.h" +#include "Plot.h" +#include "orbitframes/OrbitFrameIJK.h" +#include "orbitstaterep/PositionVelocity.h" +#include "LinearInterpolator.h" + +#include +using namespace std; +using namespace O_SESSAME; + +/*! \brief Force function that will be called each timestep */ +Vector OrbitForcesFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState) +{ + Vector Forces; + Vector Position(3); Position(_) = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase,VectorIndexBase+2)); + Forces = -398600.4418 / pow(norm2(Position),3) * Position; + return Forces; +} + +Vector OrbitForcesWithDragFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState) +{ + Vector Forces; + Vector Position(3); Position(_) = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase,VectorIndexBase+2)); + + double BC = 0.5; + Vector Vrel(3); Vrel = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase+3,VectorIndexBase+5)); + double Vrel_mag = norm2(Vrel); + Forces = -398600.4418 / pow(norm2(Position),3) * Position; + + Forces += -1/2 *1/BC * pow(Vrel_mag,2) * Vrel / Vrel_mag; + return Forces; +} + +int main() +{ + ///////////////////////////////////////////////// + // Setup an integrator and any special parameters + RungeKuttaFehlbergIntegrator myIntegrator; + int numOrbits = 1; + int numSteps = 100; + cout << "Number of Orbits: " << flush; + cin >> numOrbits; + cout << "Number of Integration Steps: "<< flush; + cin >> numSteps; + //myIntegrator.SetNumSteps(numSteps); + + vector integrationTimes; + ssfTime begin(0); + ssfTime end(begin + 92*60*numOrbits); + integrationTimes.push_back(begin); + integrationTimes.push_back(end); + + ///////////////////////////////////////////////// + // Create & initialize an orbit type + OrbitState myOrbit; + myOrbit.SetStateRepresentation(new PositionVelocity); + myOrbit.SetOrbitFrame(new OrbitFrameIJK); + Vector initPV(6); + initPV(VectorIndexBase+0) = -5776.6; // km/s + initPV(VectorIndexBase+1) = -157; // km/s + initPV(VectorIndexBase+2) = 3496.9; // km/s + initPV(VectorIndexBase+3) = -2.595; // km/s + initPV(VectorIndexBase+4) = -5.651; // km/s + initPV(VectorIndexBase+5) = -4.513; // km/s + myOrbit.GetStateRepresentation()->SetPositionVelocity(initPV); + + SpecificFunctor OrbitForcesFunctor(&OrbitForcesWithDragFunctor); + + ///////////////////////////////////////////////// + // Create the matrix of parameters needed for the RHS + Matrix Parameters(1,1); + Parameters(MatrixIndexBase,MatrixIndexBase) = 398600.4418; //km / s^2 + + + ///////////////////////////////////////////////// + cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl; + cout << "Orbit State: " << ~myOrbit.GetStateRepresentation()->GetPositionVelocity() << endl; + + // Integrate over the desired time interval + tick(); + Matrix history = myIntegrator.Integrate( + integrationTimes, // seconds + &TwoBodyDynamics, + myOrbit.GetStateRepresentation()->GetPositionVelocity(), + NULL, + NULL, + Parameters, + OrbitForcesFunctor + ); + + cout << "finished propagating in " << tock() << " seconds." << endl; + + ///////////////////////////////////////////////// + // Plot the flight history + //cout << history; + Matrix plotting = history(_,_(MatrixIndexBase+1,MatrixIndexBase+3)); + + Plot3D(plotting); + + ///////////////////////////////////////////////// + // Store the output to file + ofstream ofile; + ofile.open("OrbitHistory.dat"); + ofile << history; + ofile.close(); + + ////////////////////////////////////////////////////////////// + // Create an OrbitHistory object (uses a LinearInterpolator) + OrbitHistory myOrbHistory; + myOrbHistory.SetInterpolator(new LinearInterpolator); + Vector PosVel(6); + for(int jj = 1;jj <= history[MatrixRowsIndex].getIndexBound(); ++jj) + { + PosVel(_) = ~history(jj,_(2,7)); + myOrbit.GetStateRepresentation()->SetPositionVelocity(PosVel); + myOrbHistory.AppendHistory(history(jj,1), myOrbit); + } + + /////////////////////////////////////////////////////////// + // Ask the user for a specified time to inspect the state. + double inspectTime; + cout << "Output state at time (s): " << flush; + cin >> inspectTime; + ssfTime myTime(inspectTime); + myOrbHistory.GetState(myTime, myOrbit); + cout << myTime.GetSeconds() << " : " << ~myOrbit.GetStateRepresentation()->GetPositionVelocity() << endl; + + return 0; +} + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testOrbitIntegration.cpp,v $ +* Revision 1.4 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.3 2003/05/13 18:56:15 nilspace +* Fixed to work with new integrators, History, and interpolation. +* +* Revision 1.2 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 23:05:58 nilspace +* Initial submission. +* +* +******************************************************************************/ + + diff --git a/src/test/testPropagation.cpp b/src/test/testPropagation.cpp new file mode 100644 index 0000000..314ddf6 --- /dev/null +++ b/src/test/testPropagation.cpp @@ -0,0 +1,288 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file testPropagation.cpp +* \brief Sample of an orbit and attitude propagation using components of the SSF. +* \author $Author: nilspace $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/05/27 17:47:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// +#include "Matrix.h" +#include "Rotation.h" +#include "Attitude.h" +#include "Orbit.h" +#include "CombinedNumericPropagator.h" +#include "RungeKuttaIntegrator.h" +#include "orbitmodels/TwoBodyDynamics.h" +#include "EarthCentralBody.h" +#include "OrbitState.h" +#include "AttitudeState.h" +#include "orbitstaterep/PositionVelocity.h" +#include "orbitframes/OrbitFrameIJK.h" +#include "Plot.h" +using namespace O_SESSAME; + +NumericPropagator* SetupPropagator(); +Environment* SetupEnvironment(); +Orbit* SetupOrbit(); +Attitude* SetupAttitude(); +void myOrbitStateConvFunc(const Matrix &_meshPoint, OrbitState &_convertedOrbitState); +void myAttitudeStateConvFunc(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState); + +int main() +{ + cout << "Calling SetupOrbit()" << endl; + Orbit* myOrbit = SetupOrbit(); + cout << "Calling SetupAttitude()" << endl; + Attitude* myAttitude = SetupAttitude(); + + // Setup Propagator + cout << "Calling SetupPropagator()" << endl; + NumericPropagator* myPropagator = SetupPropagator(); + myOrbit->SetPropagator(myPropagator); + myAttitude->SetPropagator(myPropagator); + + // Setup external environment + cout << "Calling SetupEnvironment()" << endl; + Environment* myEnvironment = SetupEnvironment(); + myOrbit->SetEnvironment(myEnvironment); + myAttitude->SetEnvironment(myEnvironment); + + // Integration Times + double numOrbits = 1/10.0; + cout << "Number of Orbits: " << flush; +// cin >> numOrbits; + vector integrationTimes; + ssfTime begin(0); + ssfTime end(begin + 92*60*numOrbits); + integrationTimes.push_back(begin); + integrationTimes.push_back(end); + cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl; + cout << "Orbit State: " << ~myOrbit->GetStateObject().GetState() << endl; + cout << "Attitude State: " << ~myAttitude->GetStateObject().GetState() << endl; + + // Integrate over the desired time interval + tick(); + myPropagator->Propagate(integrationTimes, myOrbit->GetStateObject().GetState(), myAttitude->GetStateObject().GetState()); + ssfSeconds calcTime = tock(); + cout << "finished propagating in " << calcTime << " seconds." << endl; + +for (int ii = 0; ii < 2 ; ++ii) +{ + // Integrate again + integrationTimes[0] = integrationTimes[1]; + integrationTimes[1] = integrationTimes[0] + 92*60*numOrbits; + cout << integrationTimes[0] << " -> " << integrationTimes[1] << endl; + myPropagator->Propagate(integrationTimes, myOrbit->GetStateObject().GetState(), myAttitude->GetStateObject().GetState()); +} + + Matrix orbitHistory = myOrbit->GetHistory().GetHistory(); + Matrix orbitPlotting = orbitHistory(_,_(MatrixIndexBase+1,MatrixIndexBase+3)); + Matrix attitudeHistory = myAttitude->GetHistory().GetHistory(); + Matrix attitudePlotting = attitudeHistory(_,_(MatrixIndexBase,MatrixIndexBase+4)); + + + Plot3D(orbitPlotting); +// Plot attitudePlot(attitudePlotting); + Plot2D(attitudePlotting); + + // Store the output to file + ofstream ofile; + ofile.open("OrbitHistory.dat"); + ofile << myOrbit->GetHistory().GetHistory(); + ofile.close(); + + ofile.open("AttitudeHistory.dat"); + ofile << myAttitude->GetHistory().GetHistory(); + ofile.close(); + + return 0; + +} + +// ************************* +// ****** ENVIRONMENT ****** +// ************************* +// Force function that will be called each timestep +Vector GravityForceFunction(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) +{ +// Vector state = _currentOrbitState.GetState(); + static Vector Forces(3); +// Vector Position(3); Position(_) = state(_(VectorIndexBase,VectorIndexBase+2)); + static Vector Position(3); Position(_) = _currentOrbitState.GetState()(_(VectorIndexBase,VectorIndexBase+2)); + Forces = -398600.441 / pow(norm2(Position),3) * Position; + return Forces; +} + +Vector DragForceFunction(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList) +{ + static Vector Forces(3); + double BC = *(reinterpret_cast(_parameterList[0])); + static Vector Vrel(3); Vrel(_) = _currentOrbitState.GetState()(_(VectorIndexBase+3,VectorIndexBase+5)); + double Vrel_mag = norm2(Vrel); + double rho = *(reinterpret_cast(_parameterList[1])); + Forces = -1/2 * rho / BC * pow(Vrel_mag,2) * Vrel / Vrel_mag; + return Forces; +} + +Environment* SetupEnvironment() +{ + // ENVIRONMENT TESTING + Environment* pEarthEnv = new Environment; + EarthCentralBody *pCBEarth = new EarthCentralBody; + pEarthEnv->SetCentralBody(pCBEarth); + + // Add Gravity force function + cout << "Filling Parameters" << endl; + EnvFunction TwoBodyGravity(&GravityForceFunction); + pEarthEnv->AddForceFunction(TwoBodyGravity); + + // Add Drag Force Function + EnvFunction DragForce(&DragForceFunction); + double *BC = new double(200); + DragForce.AddParameter(reinterpret_cast(BC), 1); + double *rho = new double(1.13 * pow(static_cast(10), static_cast(-12))); // kg/m^3 + DragForce.AddParameter(reinterpret_cast(rho), 2); + pEarthEnv->AddForceFunction(DragForce); + + cout << "Finished Setting up Earth Environment" << endl; + return pEarthEnv; +} + +// ************************* +// ****** PROPAGATOR ******* +// ************************* +NumericPropagator* SetupPropagator() +{ + CombinedNumericPropagator* myProp = new CombinedNumericPropagator; + + // Create & setup the integator + // Setup an integrator and any special parameters + RungeKuttaIntegrator* orbitIntegrator = new RungeKuttaIntegrator; + RungeKuttaIntegrator* attitudeIntegrator = new RungeKuttaIntegrator; + + orbitIntegrator->SetNumSteps(100); + myProp->SetOrbitIntegrator(orbitIntegrator); + attitudeIntegrator->SetNumSteps(1000); + myProp->SetAttitudeIntegrator(attitudeIntegrator); + + myProp->SetOrbitStateConversion(&myOrbitStateConvFunc); + myProp->SetAttitudeStateConversion(&myAttitudeStateConvFunc); + return myProp; +} + +// ************************* +// ********* ORBIT ********* +// ************************* +void myOrbitStateConvFunc(const Matrix &_meshPoint, OrbitState &_convertedOrbitState) +{ + static Vector tempVector(_meshPoint[MatrixColsIndex].getIndexBound() - 1); + tempVector(_) = ~_meshPoint(_,_(MatrixIndexBase+1, _meshPoint[MatrixColsIndex].getIndexBound())); + _convertedOrbitState.SetState(tempVector); + return; +} + +Orbit* SetupOrbit() +{ + Orbit* myOrbit = new Orbit; + + // Create & initialize the orbit + OrbitState myOrbitState; + myOrbitState.SetStateRepresentation(new PositionVelocity); + myOrbitState.SetOrbitFrame(new OrbitFrameIJK); + Vector initPV(6); + // Space station + initPV(VectorIndexBase+0) = -5776.6; // km + initPV(VectorIndexBase+1) = -157; // km + initPV(VectorIndexBase+2) = 3496.9; // km + initPV(VectorIndexBase+3) = -2.595; // km/s + initPV(VectorIndexBase+4) = -5.651; // km/s + initPV(VectorIndexBase+5) = -4.513; // km/s + myOrbitState.SetState(initPV); + myOrbit->SetStateObject(myOrbitState); + + myOrbit->SetDynamicsEq(&TwoBodyDynamics); + + // Setup Parameters (ie mass, etc) + Matrix Parameters(1,1); + Parameters(MatrixIndexBase,MatrixIndexBase) = 398600.441; //km / s^2 + myOrbit->SetParameters(Parameters); + return myOrbit; +} + + +// ************************* +// ******* ATTITUDE ******** +// ************************* +void myAttitudeStateConvFunc(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState) +{ + static Vector tempQ(4); tempQ(_) = ~_meshPoint(_,_(2, 5)); + static Vector tempVector(3); tempVector(_) = ~_meshPoint(1, _(6, 8)); + _convertedAttitudeState.SetState(Rotation(Quaternion(tempQ)), tempVector); + return; +} +static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + static Vector stateDot(7); + static Matrix bMOI(3,3); + static Matrix qtemp(4,3); + static Matrix Tmoment(3,1); + static Vector qIn(4); + static Vector wIn(3); + qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3)); + wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6)); + qIn /= norm2(qIn); + +// _attitudeState->SetState(Rotation(Quaternion(qIn)), wIn); // Need to speed up in some way + qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3); + qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2))); + qtemp(_,MatrixIndexBase) = 0.5 * qtemp * wIn; + + bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2)); + Tmoment(_,_) = (_forceFunctorPtr.Call(_time, _Orbit->GetStateObject(), _Attitude->GetStateObject()))(_); + Tmoment = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn))); + + stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = qtemp(_,MatrixIndexBase); + stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = Tmoment(_,MatrixIndexBase); + + return stateDot; +} + +Attitude* SetupAttitude() +{ + Attitude* myAttitude = new Attitude; + + AttitudeState myAttitudeState; + myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1))); + Vector initAngVelVector(3); + initAngVelVector(1) = 0.1; + myAttitudeState.SetAngularVelocity(initAngVelVector); + + myAttitude->SetStateObject(myAttitudeState); + myAttitude->SetDynamicsEq(&AttituteDynamics); + myAttitude->SetParameters(eye(3)); + + return myAttitude; + +} + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testPropagation.cpp,v $ +* Revision 1.4 2003/05/27 17:47:13 nilspace +* Updated example to have seperate orbit & attitude integrators. +* +* Revision 1.3 2003/05/20 19:24:43 nilspace +* Updated. +* +* Revision 1.2 2003/05/13 18:57:32 nilspace +* Clened up to work with new Propagators. +* +* Revision 1.1 2003/05/01 02:42:47 nilspace +* New propagation test file. +* +* +******************************************************************************/ + + diff --git a/src/test/testRotation.cpp b/src/test/testRotation.cpp new file mode 100644 index 0000000..4b0fa7c --- /dev/null +++ b/src/test/testRotation.cpp @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file testRotation.cpp +* \brief Test program testing & verifying the rotation library. +* \author $Author: nilspace $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/08/24 20:59:13 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "Rotation.h" +#include "Matrix.h" +#include "ASCIIConverter.h" +#include "BinaryConverter.h" +#include "MatrixConversionForm.h" + +using namespace O_SESSAME; + +int main() +{ + Quaternion qInit(0,0,0,1); + Rotation rotInit(qInit); + cout << "q - R(q) = " << qInit - rotInit.GetQuaternion() << endl; + cout << "R(q)->DCM = " << rotInit.GetDCM() << endl; + Rotation rot2(Quaternion(0.5,0.5,0.5,0.5)); + cout << "R(q(0.5,0.5,0.5,0.5)) = " << rot2.GetDCM() << endl; + + Rotation Rot321(Deg2Rad(10),Deg2Rad(0.1),Deg2Rad(-5),321); + cout << "R(10, 0.1, -5, 321) (degs) = " << Rot321.GetDCM() << endl; + cout << "R(10, 0.1, -5, 321) (degs) = " << Rot321.GetDCM().GetQuaternion().GetDCM() << endl; + + + cout << "R1(-2)" << setprecision(15) << R1(Deg2Rad(-2)) << endl; + cout << "R2(-5)" << setprecision(15) << R2(Deg2Rad(-5)) << endl; + cout << "R3(-10)" << setprecision(15) << R3(Deg2Rad(10)) << endl; + DirectionCosineMatrix DCM1(Deg2Rad(10),Deg2Rad(0.1),Deg2Rad(-5),321); + cout << "DCM(10, 0.1, -5, 321) (degs) = " << endl << setprecision(15) << DCM1 << endl; + Vector xAxis(3); + xAxis(1) = 1; + cout << ~xAxis << " -> " << ~(rot2 * xAxis) << endl; + cout << ~xAxis << " -> " << ~(rotInit * xAxis) << endl; + +// ModifiedRodriguezParameters mrp1(Quaternion(0,0.2, -0.3, .2)); + ModifiedRodriguezParameters mrp1(0,0.2, -0.3); + cout << "mrp1(0,0.2, -0.3): " << ~mrp1; + cout << "sigmaSq = " << (~mrp1 * mrp1); + cout << "mrp1->Quat: " << ~mrp1.GetQuaternion(); +// Rotation rot3(mrp1); + Rotation rot3(mrp1.GetQuaternion()); + cout << "Rot3->Quat->MRP: " << ~rot3.GetQuaternion().GetMRP(); + cout << "Rot3->MRP: " << ~rot3.GetMRP() << endl; + cout << "Rot3->Quat: " << ~rot3.GetQuaternion(); + cout << "Rot3.DCM->Quaternion: " << ~rot3.GetDCM().GetQuaternion() << endl; + cout << "mrp1->DCM: " << endl << mrp1.GetDCM() << endl; + cout << "mrp->Quat->DCM: " << endl << mrp1.GetQuaternion().GetDCM() << endl; + cout << "Rot3.DCM: " << endl << rot3.GetDCM() << endl; + + // Text save & restore + MatrixConversionForm convForm; + ASCIIConverter rotOutput("rotationSave.txt"); + convForm.SetMatrix(rot3.GetDCM()); + rotOutput.Export(convForm); + + ASCIIConverter rotInput("rotationSave.txt"); + rotInput.Import(convForm); + cout << "Imported Matrix: " << convForm.GetMatrix(); + Rotation rotImport(convForm.GetMatrix()); + cout << "Rot3_Import MRP: " << ~rotImport.GetMRP(); + + // Binary save & restore + MatrixConversionForm binConvForm; + convForm.SetMatrix(rot3.GetDCM()); + BinaryConverter rotOutputBIN("rotationSave"); + convForm.SetMatrix(rot3.GetDCM()); + rotOutputBIN.Export(convForm); + + BinaryConverter rotInputBIN("rotationSave"); + rotInputBIN.Import(binConvForm); + cout << "Imported Matrix: " << binConvForm.GetMatrix(); + Rotation rotImportBin(binConvForm.GetMatrix()); + cout << "Rot3_Import Binary MRP: " << ~rotImportBin.GetMRP(); + return 0; +} + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: testRotation.cpp,v $ +* Revision 1.4 2003/08/24 20:59:13 nilspace +* Updated. +* +* Revision 1.3 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/03/25 02:26:00 nilspace +* initial submission of test files. +* +******************************************************************************/ diff --git a/src/utils/CVS/Entries b/src/utils/CVS/Entries new file mode 100644 index 0000000..77d77e7 --- /dev/null +++ b/src/utils/CVS/Entries @@ -0,0 +1,20 @@ +/Functor.h/1.10/Sat Oct 18 21:37:28 2003// +/Integrator.h/1.10/Sat Oct 18 21:37:28 2003// +/Interpolator.h/1.3/Fri Jun 6 00:34:47 2003// +/Jamfile/1.6/Mon Dec 8 16:48:36 2003// +/LinearInterpolator.cpp/1.3/Tue May 20 19:46:52 2003// +/LinearInterpolator.h/1.2/Fri Jun 6 00:34:47 2003// +/MathUtils.h/1.2/Thu May 22 03:00:07 2003// +/Plot.cpp/1.4/Sat Oct 18 21:37:28 2003// +/Plot.h/1.6/Sat Oct 18 21:37:28 2003// +/RungeKutta.h/1.4/Sat Oct 18 21:37:28 2003// +/RungeKuttaFehlbergIntegrator.cpp/1.5/Thu Jun 5 20:30:52 2003// +/RungeKuttaFehlbergIntegrator.h/1.5/Thu Jun 5 20:09:14 2003// +/RungeKuttaIntegrator.cpp/1.7/Thu May 22 02:59:15 2003// +/RungeKuttaIntegrator.h/1.8/Thu May 22 02:59:15 2003// +/Time.cpp/1.10/Sat Oct 18 22:02:11 2003// +/Time.h/1.15/Sat Oct 18 21:54:44 2003// +/TimeCompat.cpp/1.1/Sat Oct 18 21:37:29 2003// +/math.pro/1.4/Sat Oct 18 21:37:29 2003// +/utils.pro/1.4/Sat Oct 18 21:37:29 2003// +D diff --git a/src/utils/CVS/Repository b/src/utils/CVS/Repository new file mode 100644 index 0000000..764b200 --- /dev/null +++ b/src/utils/CVS/Repository @@ -0,0 +1 @@ +spacecraft/src/utils diff --git a/src/utils/CVS/Root b/src/utils/CVS/Root new file mode 100644 index 0000000..951726a --- /dev/null +++ b/src/utils/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@spacecraft.cvs.sourceforge.net:/cvsroot/spacecraft diff --git a/src/utils/Functor.h b/src/utils/Functor.h new file mode 100644 index 0000000..69949b6 --- /dev/null +++ b/src/utils/Functor.h @@ -0,0 +1,155 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Functor.h +* \brief Implementation of a Functor class for vectors. +* \author $Author: rsharo $ +* \version $Revision: 1.10 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_FUNCTOR_H__ +#define __SSF_FUNCTOR_H__ + +#include +#include "utils/Time.h" +#include "OrbitState.h" +#include "AttitudeState.h" + +namespace O_SESSAME { + +/*! \brief Abstract class to hold the pointer to an force calculating functor. +* \ingroup IntegrationLibrary +* \ingroup EnvironmentToolkit +* +* A @em Function @em Object, or @em Functor (the two terms are synonymous) is simply +any object that can be called as if it is a function. It is used to define a call-back function that evaluates +any algorithm that takes the defined inputs and returns a vector of values. Examples of usage include +evaluating a disturbance force or torque given the current time, orbit state, and attitude state. The returned +vector will then be the 3 forces (or torques). + +\par Examples: +The simplest functor is a placeholder that can be set to just return a vector of zeros: +\code +Vector NullFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState) +{ + return Vector(3); +} +\endcode +This isn't very useful, but may be necessary for filling out a parameter list such as for \sa Integrator that +requests a Functor call-back function. The Functor object is created as follows: +\code +SpecificFunctor AttitudeForcesFunctor(&NullFunctor); +\endcode +SpecificFunctor is used since it is only a function that was used, and not a member function of a class. For that +case, an ObjectFunctor is required which stores the type (or class) of the function as well as the pointer to +the function itself. + +\par +An ObjectFunctor may be assigned from an Environment object (@em pEarthEnv) where the function is @em GetForces: +\code +ObjectFunctor OrbitForcesFunctor(pEarthEnv, &Environment::GetForces); +\endcode +To review, we are creating an ObjectFunctor that will hold a call-back function to the Environment class (hence +the template argument ). The function, @em OrbitForcesFunctor, needs a pointer to the instance +of the class we are using (@em pEarthEnv), and the reference to the function (@em &Environment::GetForces). The +@em \& is required to specify that it is a @em reference, and the @em Environment:: defines the scope of the +function @em GetForces. It is also important to note that the @em GetForces function conforms to the ObjectFunctor +interface. (\sa Environment::GetForces). + +* \todo make Functors for variety of function types +*/ +class Functor +{ +public: + + // two possible functions to call member function. virtual cause derived + // classes will use a pointer to an object and a pointer to a member function + // to make the function call + virtual Vector Call(const ssfTime&, const OrbitState&, const AttitudeState&) const =0; // call using function +}; + +/*! \brief derived template class +* \ingroup IntegrationLibrary +* \ingroup EnvironmentToolkit +* +*/ +class SpecificFunctor : public Functor +{ +private: + Vector (*fpt)(const ssfTime&, const OrbitState&, const AttitudeState&); // pointer to member function + +public: + + // constructor - takes pointer to a Function + SpecificFunctor(Vector(*_fpt)(const ssfTime&, const OrbitState&, const AttitudeState&)):fpt(_fpt) {}; + + // override function "Call" + virtual Vector Call(const ssfTime &_ssfTime, const OrbitState &_orbState, const AttitudeState &_attState) const { return (*fpt)(_ssfTime, _orbState, _attState);}; // execute member function +}; + +/*! \brief derived template class +* \ingroup IntegrationLibrary +* \ingroup EnvironmentToolkit +* +*/ +template class ObjectFunctor : public Functor +{ +private: + TClass* pt2Object; /*!< pointer to object */ + Vector (TClass::*fpt)(const ssfTime&, const OrbitState&, const AttitudeState&); /*!< pointer to member function */ + +public: + + /*! constructor - takes pointer to an object and pointer to a member and stores + * them in two private variables */ + ObjectFunctor(TClass* _pt2Object, Vector(TClass::*_fpt)(const ssfTime&, const OrbitState&, const AttitudeState&)): pt2Object(_pt2Object), fpt(_fpt) {}; + ObjectFunctor(): pt2Object(NULL), fpt(NULL) {}; + void Set(TClass* _pt2Object, Vector(TClass::*_fpt)(const ssfTime&, const OrbitState&, const AttitudeState&)){ pt2Object = _pt2Object; fpt=_fpt; }; + + // override function "Call" + virtual Vector Call(const ssfTime &_ssfTime, const OrbitState &_orbState, const AttitudeState &_attState) const { return (*pt2Object.*fpt)(_ssfTime, _orbState, _attState);}; // execute member function +}; +} // close namespace O_SESSAME + +#endif /* __SSF_FUNCTOR_H__ */ + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Functor.h,v $ +* Revision 1.10 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.9 2003/05/21 19:52:22 nilspace +* Updated comments. +* +* Revision 1.8 2003/05/20 17:44:20 nilspace +* Updated comments. +* +* Revision 1.7 2003/05/13 18:58:04 nilspace +* Cleaned up comments. +* +* Revision 1.6 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.5 2003/04/25 18:55:45 nilspace +* Implemented ObjectFunctor body (empty), and moved constructor assignments to inline with constructor. +* +* Revision 1.4 2003/04/25 13:45:53 nilspace +* const'd Get() functions. +* +* Revision 1.3 2003/04/24 20:00:10 nilspace +* Made all Call() functions const to prevent warnings. +* +* Revision 1.2 2003/04/24 13:51:10 nilspace +* Added a Set function for setting the object & function afterwards, or by using the default constructor. +* +* Revision 1.1 2003/04/08 22:33:06 nilspace +* Initial Submission +* +* +******************************************************************************/ diff --git a/src/utils/Integrator.h b/src/utils/Integrator.h new file mode 100644 index 0000000..07310cc --- /dev/null +++ b/src/utils/Integrator.h @@ -0,0 +1,200 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Integrator.h +* \brief Abstract interface to the Integrator Strategy. +* \author $Author: rsharo $ +* \version $Revision: 1.10 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_INTEGRATOR_H__ +#define __SSF_INTEGRATOR_H__ + +#include +#include "Functor.h" +#include "utils/Time.h" +#include +using namespace std; +namespace O_SESSAME { +class Orbit; +class Attitude; + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup IntegrationLibrary Integration Library */ +/* @{ */ + +/*! \brief A generalized pointer to a function that takes a vector as a parameter and returns a vector */ +typedef Vector (*vectorFuncPtr)(const Vector& _vectorFuncPtrParams); + +/*! \brief defines a pointer to an integrator's right-hand side (RHS) function */ +typedef Vector (*odeFunc)(const double& _time, const Vector& _state, const Matrix& _parameters, vectorFuncPtr _funcPtr); +//typedef Vector(*odeFunc)(const double& _time, const Vector& _states, const Matrix& _params); + +/*! \brief defines a pointer to an integrator's right-hand side (RHS) function using a functor for the arbitrary vector function +* +* @param _time This is the time at this step of the integration +* @param _integratingState This is the current state at the time of integration. The state can be any vector + of values the user desires to integrate, such as quaternions, angular momentum, energy, or position. These values + are the result of the time derivative values being combined through the integration. +* @param _pOrbit This is a pointer to an Orbit object. It is only necessary if the RHS function needs to inspect values of + the orbit (OrbitHistory, OrbitState, etc.). If the user does not need to use the orbit object, the integration function will + have passed in a NULL value (pointer to nothing), and the orbit object should not be used. +* @param _pAttitude This is a pointer to an Attitude object. It is only necessary if the RHS function needs to inspect values of + the attitude (AttitudeHistory, AttitudeState, etc.). If the user does not need to use the attitude object, the integration function will + have passed in a NULL value (pointer to nothing), and the attitude object should not be used. +* @param _parameters This is a matrix of constants that is passed to the RHS function for the user to store constants throughout + the integration. Examples include the Moment of Inertia matrix, mass, ballistic coefficient, etc. The matrix can be any size, but the + user needs to note how values were stored into the matrix in order to correctly extract them. (ex the first 3x3 sub-matrix is the MOI, + while element (4,1) is the mass, and element (4,2) is the drag area). +* @param _forceFunctorPtr This is a call-back function meant for use in calculating disturbance functions. By setting this reference to a + force or torque disturbance function, the user can call this function within the RHS function, giving the current (integrated) states + as parameters to calculate the instantaneous disturbance vector. (see Functor) +* The right-hand side (RHS) is the function that calculates the time derivatives of the state: \f$\dot{\bf x}=f(t,{\bf x})\f$. +The type @em odeFunctor is a definition of the interface to the RHS function, which requires the calculation time, state at that time, +a possible pointer to an Orbit and Attitude Object, a matrix of parameter constants, and a call-back function pointer that can be used to +evaluate any function of OrbitState and AttitudeState. An Example of a RHS function for 2-body orbital dynamics is: +\code +static Vector TwoBodyDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, const Matrix &_parameters, const Functor &_forceFunctorPtr) +{ + static Vector Forces(3); + static Vector Velocity(3); + static Vector stateDot(6); + static OrbitState orbState + (new PositionVelocity); + + orbState.GetStateRepresentation()->SetPositionVelocity(_integratingState); + + Forces = _forceFunctorPtr.Call(_time, orbState, _Attitude->GetStateObject()); + Velocity(_) = _integratingState(_(VectorIndexBase+3,VectorIndexBase+5)); + + stateDot(_(VectorIndexBase, VectorIndexBase+2)) = Velocity(_); + stateDot(_(VectorIndexBase+3, VectorIndexBase+5)) = Forces(_); + return stateDot; +} +\endcode +*/ +typedef Vector (*odeFunctor)(const ssfTime& _time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, const Matrix& _parameters, const Functor& _forceFunctorPtr); +/** @} */ + +/*! \class Integrator +* \brief Interface class to the Integrator algorithm strategies. +* \ingroup IntegrationLibrary +* +* This class defines the functions that are required for all Integrator types (ie \sa RungeKuttaIntegrator, +\sa AdamsBashfourthIntegrator, etc). + +\par +Integration in the Open-Sessame Framework is modeled after integration in
MatLab. +To integrate, a user must specify a Right-Hand Side (RHS) function that has the form \f$\dot{\bf x} = f\left(t,{\bf x}, {\bf P}, T(t, {\bf x})\right)\f$, +where \f$t\f$ is the time (in seconds), \f${\bf x}\f$ is the vector of states being integrated, \f${\bf P}\f$ is a matrix of constants, and +\f$T(t, {\bf x})\f$ is a reference to an external function which can be used to evaluate other parameters necessary +for the RHS equation. The integration strategy will then evaluate the function \f$f\f$ at various timesteps, depending on the +integration algorithm, and combine the results together to approximate the integrated solution. + +\par +Integration is specifically useful in the Open-Sessame Framework for numerically evaluating the equations of motion (EOM) +of a spacecraft. The attitude \& orbit EOM are usually defined as the time rate of change of the states (rotations, angular +velocities, position, angular momentum, energy, etc) which can be integrated to determine the +state of the spacecraft at some future time. For example, to evaluate the quaternion at some time \f$T\f$: +\f[\frac{d\bar{\bf q}}{dt} = \dot{\bar{\bf q}} \Rightarrow d\bar{\bf q} = \dot{\bar{\bf q}} dt\f] +\f[ \bar{\bf q}(T) = \int^{T}_{0}{\dot{\bar{\bf q}}(t, \bar{\bf q}(T)) dt} \f] + +\example testAttitudeIntegration.cpp +\example testOrbitIntegration.cpp +*/ +class Integrator +{ +public: + /*! Standard Integration Function */ +// virtual Matrix Integrate(const Vector& _propTime, odeFunc _FuncPtr, const Vector& _initialConditions, const Matrix& _constants, vectorFuncPtr _vectorFuncPtr) = 0; + + + /*! Interface to the Orbit \& Attitude integration function. + * + * This function defines just the interface to any of the derived integration strategies. Because it + * is pure virtual (virtual ... = 0;), it is not actually implemented, but defines a member function that + * is required to be implemented by all derived classes. Therefore, the user can be assured this integration + * function will exist for all derived classes. + * + * @param _propTime This input variable specifies the list of integration times, from the starting value (first time) to the ending integration (last time) with the specified intervals. + * This vector is built by creating ssfTime object, and "push_back" them onto the vector list: + * \code + * vector integrationTimes; + * ssfTime begin(0); + * ssfTime end(begin + 20); + * integrationTimes.push_back(begin); + * integrationTimes.push_back(end); + * \endcode + * @param _FunctorPtr This is the reference (see odeFunctor) to the Right-Hand side (RHS) of the integration equation. It should be a single function that computes the time derivative + * of the state given the time, current state, and other parameters. + * @param _initialConditions The vector of initial conditions of the state being integrated. It can be any sized. And should be in the order specified by the user. + (ex. \f$[q_1, q_2, q_3, q_4, \omega_1, \omega_2, \omega_3]^{T}\f$) + * @param _Orbit This is a pointer to an Orbit object. It will be passed directly to the RHS and may be used for evaluating the dynamics or disturbance torque/forces. + * However, if no orbit is required, or used, the user should only pass a NULL pointer and the orbit object shouldn't be used in the user's RHS function. + * @param _Attitude This is a pointer to an Attitude object. It behaves much the same way as _Orbit above. It will be passed directly to the RHS function for use in + * evaluation, but if not used, the user should only pass a NULL pointer, and the attitude object not used in the RHS function. + * @param _constants This is a matrix of constants that is required by the RHS function. The constants are passed to each evaluation of the RHS, and may be any size, and + * store any values the user requires. Examples include Moments of Inertia, ballistic coefficients, mass, etc. + Example: \f[\begin{bmatrix} I_{11} & I_{12} & I_{13} \\ I_{21} & I_{22} & I_{23} \\ I_{31} & I_{32} & I_{33} \\ mass & drag area & 0 \end{bmatrix}\f] + * @param _functorPtr The Functor is a call-back function that the RHS can use to evaluate an external function call. The prototype of the _functorPtr must correspond to the Functor + * definition, but other than that, may perform any calculations required by the user in the RHS function. + * @return The output of the integration function is a matrix of calculated integration times (meshpoints), and integrated state values at each of the meshpoints. + * \f[ + * \begin{bmatrix} + * t_0 & x_{1,0} & x_{2,0} & ...\\ + * t_1 & x_{1,1} & x_{2,1} & ...\\ + * t_2 & x_{1,2} & x_{2,2} & ...\\ + * . & . & . & . \\ + * t_{final} & x_{1,f} & x_{2,f} & ... + * \end{bmatrix} + * \f] + * where \f$t_T\f$ is the time at step T, and \f$x_{i,T}\f$ is the state value of element i, at time step T. + */ + virtual Matrix Integrate(const vector& _propTime, odeFunctor _FunctorPtr, const Vector& _initialConditions, Orbit* _pOrbit, Attitude* _pAttitude, const Matrix& _constants, const Functor& _functorPtr) = 0; +protected: +// Integrator() {}; +}; + +} // close namespace O_SESSAME + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Integrator.h,v $ +* Revision 1.10 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.9 2003/05/22 21:03:52 nilspace +* Updated comments. +* +* Revision 1.8 2003/05/22 02:59:38 nilspace +* Changed to pass pointers instead of references of Orbit & Attitude objects. +* +* Revision 1.7 2003/05/21 19:45:01 nilspace +* Updated documentation. +* +* Revision 1.6 2003/05/20 17:44:21 nilspace +* Updated comments. +* +* Revision 1.5 2003/05/13 18:58:27 nilspace +* Cleaned up comments. +* +* Revision 1.4 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.3 2003/04/25 13:45:55 nilspace +* const'd Get() functions. +* +* Revision 1.2 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:32:20 nilspace +* Initial submission. +* +* +******************************************************************************/ diff --git a/src/utils/Interpolator.h b/src/utils/Interpolator.h new file mode 100644 index 0000000..bc5492a --- /dev/null +++ b/src/utils/Interpolator.h @@ -0,0 +1,152 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Interpolator.h +* \brief Abstract interface to the Interpolator Strategy. +* \author $Author: nilspace $ +* \version $Revision: 1.3 $ +* \date $Date: 2003/06/06 00:34:47 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_INTERPOLATOR_H__ +#define __SSF_INTERPOLATOR_H__ +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#include + +namespace O_SESSAME { + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup InterpolationLibrary Interpolation Library +* \brief Interpolation schemes. +* +* \detail Interpolators are used when there is a set of computed data points, but the user +requires the approximated data between these data points. The interpolator creates a functional +approximation of the intermediate data using any number of calculated @em mesh points. + +\par +The interpolator creates and stores the parameters corresponding to the interpolation function +and functional representation. The user must enter a set of time values (independent variables) and +a set of corresponding data values to be interpolated (dependent variables). Once the interpolation +has been computer and has stored the functional representation, the user can Evaluate the interpolation +at any point in between the valid mesh points. + +\par Derived Classes +Each derived interpolation is a specific algorithm that determines an interpolation based upon the +described scheme. This may include linear, lagrangian, hermitian, or a cubic spline interpolation. +The user needs to query the GetNumberDataPoints to determine how many mesh points are required to +perform interpolation (the higher the order, the more number of data points). Some interpolations +may also require higher order terms (first- and second-derivatives) of the dependent variables. +Consult the specific class's documentation. +*/ + +/*! \brief Abstract interface to the set of interpolators. +* +* \ingroup InterpolationLibrary +* \detail +*/ +class Interpolator +{ +public: + /*! \brief Default Deconstructor */ + virtual ~Interpolator() { } + + /*! \brief Standard Interpolation Function. + * + * @param _timePoints Vector of time (seconds) points of the data values. + * @param _dataPoints Matrix of data points at each time step in the _timePoints vector. + *\f[\begin{bmatrix} + * x1(t1) & x2(t1) & x3(t1) & ... \\ + * x1(t2) & x2(t2) & x3(t2)& ... \\ + * x1(t3) & x2(t3) & x3(t3) & ... \\ + * ... & ... & ... & ... \\ + * \end{bmatrix}\f] + */ + virtual void Interpolate(const Vector& _timePoints, const Matrix& _dataPoints) = 0; + + /*! \brief Evaluate interpolation curve at a specified time. + * + * \detail Output = m_Slope * _inputPoint + m_Offset + * @param _inputPoint Input point (time) at which to evaluate the vector of interpolations. + * @return Vector of output values from the evaluated interpolation. + */ + virtual Vector Evaluate(const double& _inputPoint) = 0; + /*! \brief Returns the number of data points required for interpolation. + * + * \detail the number of data points is the number of X-values (time) required to interpolate. + * @return the number of data points, centered about the evaluation time, req'd to interpolate. + */ + virtual int GetNumberDataPoints() = 0; + + /*! \brief Return a pointer to a new instance of a derived interpolator type. + * + * \detail This is used to request memory for a new instance of a derived instance when the + * actual type of the derived object is unknown. By calling this function, the compiler + * links to the correct derived function to return a pointer and allocate memory of + * the correct type. + * \par Example: + * \code + * Interpolator* newInterp = oldInterp->NewPointer(); + * \endcode + * @return a pointer to a new allocation of memory for the appropriate interpolator. + */ + virtual Interpolator* NewPointer() = 0; + + /*! \brief Return a pointer to a copy of a derived interpolator type. + * + * \detail This is used to request memory for and copy of an instance of a derived representation when the + * actual type of the derived object is unknown. By calling this function, the compiler + * links to the correct derived function to return a pointer and allocate memory of + * the correct type and copy the data. + * \par Example: + \code + * Interpolator* newInterp = oldInterp->Clone(); + \endcode + * @return a pointer to a copy of the appropriate interpolator. + */ + virtual Interpolator* Clone() = 0; + + /*! \brief Returns whether the current interpolation parameters are valid. + * @return TRUE if the current interpolation is valid, FALSE if it is not and should not be used to Evaluate without being reinterpolated. + */ + virtual bool GetValid() {return m_Valid;}; + +protected: + /*! \brief Sets the validity value of the interpolation parameters. + * + */ + virtual void SetValid(const bool& _newValidValue) {m_Valid = _newValidValue;}; + + /*! \brief Default constructor. Does nothing since this is an abstract class + * + * \detail Specifically, it sets the default value of the m_Valid flag. + */ + Interpolator() : m_Valid(FALSE) { }; + +private: + /*! \brief Internal storage of the interpolation's "validity" */ + bool m_Valid; +}; +} // close namespace O_SESSAME + +#endif + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Interpolator.h,v $ +* Revision 1.3 2003/06/06 00:34:47 nilspace +* ? +* +* Revision 1.2 2003/05/15 16:05:44 nilspace +* Added a TRUE and FALSE define. Move to a math header file. +* +* Revision 1.1 2003/05/13 18:41:23 nilspace +* Initial submission. +* +* +******************************************************************************/ diff --git a/src/utils/Jamfile b/src/utils/Jamfile new file mode 100644 index 0000000..42eb5c6 --- /dev/null +++ b/src/utils/Jamfile @@ -0,0 +1,45 @@ +########################################### +# +# Jamfile for the utils level directory +# +# +# $Author: simpliciter $ +# $Revision: 1.6 $ +# $Date: 2003/12/08 16:48:36 $ +########################################### + +SubDir OPENSESSAME_ROOT src utils ; + + +Objects LinearInterpolator.cpp RungeKuttaFehlbergIntegrator.cpp RungeKuttaIntegrator.cpp ; +ObjectHdrs LinearInterpolator.cpp RungeKuttaFehlbergIntegrator.cpp RungeKuttaIntegrator.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)math : LinearInterpolator$(SUFOBJ) RungeKuttaFehlbergIntegrator$(SUFOBJ) RungeKuttaIntegrator$(SUFOBJ) ; + +Objects Plot.cpp Time.cpp TimeCompat.cpp ; +ObjectHdrs Plot.cpp Time.cpp TimeCompat.cpp : $(OPENSESSAME_HDRS) ; + +LibraryFromObjects $(PFXLIB)utils : Plot$(SUFOBJ) Time$(SUFOBJ) TimeCompat$(SUFOBJ) ; + + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)math$(SUFLIB) ; +#InstallFile $(OPENSESSAME_INCLUDEDIR) : Integrator.h Interpolator.h LinearInterpolator.h MathUtils.h RungeKutta.h RungeKuttaFehlbergIntegrator.h RungeKuttaIntegrator.h ; + +InstallLib $(OPENSESSAME_LIBDIR) : $(PFXLIB)utils$(SUFLIB) ; +##InstallFile $(OPENSESSAME_INCLUDEDIR) : Functor.h Plot.h Time.h ; + + +# /***************************************************************************** +# * $Log: Jamfile,v $ +# * Revision 1.6 2003/12/08 16:48:36 simpliciter +# * Fixed to include utils library. +# * +# * Revision 1.5 2003/12/08 14:48:27 simpliciter +# * All new Jamfiles! +# * +# * +# * +# ******************************************************************************/ + + + diff --git a/src/utils/LinearInterpolator.cpp b/src/utils/LinearInterpolator.cpp new file mode 100644 index 0000000..d395fb5 --- /dev/null +++ b/src/utils/LinearInterpolator.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file LinearInterpolator.cpp +* \brief Implementation of the Linear Interpolator. +* \author $Author: nilspace $ +* \version $Revision: 1.3 $ +* \date $Date: 2003/05/20 19:46:52 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "LinearInterpolator.h" + +namespace O_SESSAME { +LinearInterpolator::LinearInterpolator() : m_NumDataPoints(2), m_NumElements(0), m_Slope(m_NumElements), m_Offset(m_NumElements), m_tempOutput(m_NumElements) +{ + +} + +LinearInterpolator::LinearInterpolator(const Vector& _timePoints, const Matrix& _dataPoints) : m_NumDataPoints(2), m_NumElements(_dataPoints[MatrixColsIndex].getIndexBound()), m_Slope(m_NumElements), m_Offset(m_NumElements), m_tempOutput(m_NumElements) +{ + Interpolate(_timePoints, _dataPoints); +} + +LinearInterpolator::~LinearInterpolator() +{ +} + +void LinearInterpolator::Interpolate(const Vector& _timePoints, const Matrix& _dataPoints) +{ + m_NumElements = _dataPoints[MatrixColsIndex].getIndexBound(); + if(m_Slope.getIndexBound() != m_NumElements) + m_Slope.initialize(m_NumElements); + if(m_Offset.getIndexBound() != m_NumElements) + m_Offset.initialize(m_NumElements); + + for(int ii = MatrixIndexBase; ii <= m_NumElements; ++ii) + { + BuildLinearInterpolation(_timePoints(VectorIndexBase), _dataPoints(VectorIndexBase,ii), + _timePoints(VectorIndexBase+1), _dataPoints(VectorIndexBase+1,ii), + m_Slope(ii), m_Offset(ii)); + } + SetValid(TRUE); +} + +Vector LinearInterpolator::Evaluate(const double& _timeEvalPoint) +{ + if(m_tempOutput.getIndexBound() != m_NumElements) + m_tempOutput.initialize(m_NumElements); + + for(int ii = VectorIndexBase; ii <= m_Slope.getIndexBound(); ++ii) + { + m_tempOutput(ii) = _timeEvalPoint * m_Slope(ii) + m_Offset(ii); + } + return m_tempOutput; +} + +void LinearInterpolator::BuildLinearInterpolation(const double& _x1, const double& _y1, const double& _x2, const double& _y2, double& _Slope, double& _Offset) +{ + _Slope = (_y2 - _y1) / (_x2 - _x1); + _Offset = _y2 - _Slope * _x2; +} + +LinearInterpolator* LinearInterpolator::NewPointer() +{ + return new LinearInterpolator(); +} + +LinearInterpolator* LinearInterpolator::Clone() +{ + return new LinearInterpolator(*this); +} + +} // close namespace O_SESSAME + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: LinearInterpolator.cpp,v $ +* Revision 1.3 2003/05/20 19:46:52 nilspace +* Fixed the initialization of m_NumElements and subsequent parameter vector size checks to be != rather than just < +* +* Revision 1.2 2003/05/20 17:44:21 nilspace +* Updated comments. +* +* Revision 1.1 2003/05/13 18:42:08 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/utils/LinearInterpolator.h b/src/utils/LinearInterpolator.h new file mode 100644 index 0000000..229e57a --- /dev/null +++ b/src/utils/LinearInterpolator.h @@ -0,0 +1,143 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file LinearInterpolator.h +* \brief Interface to the Linear Interpolator. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/06/06 00:34:47 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_LINEAR_INTERPOLATOR_H__ +#define __SSF_LINEAR_INTERPOLATOR_H__ + +#include +#include "Interpolator.h" + +namespace O_SESSAME { +/*! \brief Interpolates between a given set of data points to create a linear functional approximation. +* \ingroup InterpolationLibrary +* +* \detail Works for either a single function, or Vector of functions (such as interpolating a state). + +\par Example: +\code +// Interpolate the sin() function + +// Build the sin() function +int stepsize = 0.1; +Vector timeVec(2*M_PI / stepsize); +Matrix sinOutput(timeVec[MatrixRowsIndex].getIndexBound(), 1); +for (int jj = 1; jj < timeVec[MatrixRowsIndex].getIndexBound(); ++jj) +{ + timeVec(jj) = jj * stepsize; + sinOutput(jj,1) = sin(jj * stepsize); +} + +// Create interpolator +LinearInterpolator interp(timeVec,sinOutput); +Vector chk = interp.Evaluate(0.25); +\endcode +*/ +class LinearInterpolator : public Interpolator +{ +public: + /*! \brief Creates an empty linear interpolation. + * + */ + LinearInterpolator(); + + /*! \brief Creates a linear interpolation from the data points. + * + * \detail See Interpolate + */ + LinearInterpolator(const Vector& _timePoints, const Matrix& _dataPoints); + + /*! \brief Default Deconstructor + * + */ + virtual ~LinearInterpolator(); + + /*! \brief Creates an interpolation from the vector of time points and matrix of corresponding data points. + * + * @param _timePoints Vector of time (seconds) points of the data values. + * @param _dataPoints Matrix of data points at each time step in the _timePoints vector. + *\f[\begin{bmatrix} + * x1(t1) & x2(t1) & x3(t1) & ... \\ + * x1(t2) & x2(t2) & x3(t2)& ... \\ + * x1(t3) & x2(t3) & x3(t3) & ... \\ + * ... & ... & ... & ... \\ + * \end{bmatrix}\f] + */ + virtual void Interpolate(const Vector& _timePoints, const Matrix& _dataPoints); + + /*! \brief Evaluate interpolation curve at a specified time. + * + * \detail Output = m_Slope * _inputPoint + m_Offset + * @param _inputPoint Input point (time) at which to evaluate the vector of interpolations. + * @return Vector of output values from the evaluated interpolation. + */ + virtual Vector Evaluate(const double& _inputPoint); + + /*! \brief Returns the number of data points required for interpolation. + * + * \detail the number of data points is the number of X-values (time) required to interpolate. + * @return the number of data points, centered about the evaluation time, req'd to interpolate. + */ + virtual int GetNumberDataPoints() {return m_NumDataPoints;}; + + /*! \brief Return a pointer to a new instance of a linear interpolator type. + * + * \detail This is used to request memory for a new instance of a LinearInterpolator. It is necessary + * when attempting to get a pointer from the abstract data type Interpolator + * and the actual representation type isn't known. + * @return a pointer to a new allocation of memory for the LinearInterpolator object. + */ + virtual LinearInterpolator* NewPointer(); + /*! \brief Return a pointer to a copy of the linear interpolator instance. + * + * \detail This is used to request memory for a copy of this instance of LinearInterpolator. It is necessary + * when attempting to get a pointer from the abstract data type Interpolator + * and the actual representation type isn't known. + * @return a pointer to a copy of the LinearInterpolator object. + */ + virtual LinearInterpolator* Clone(); + +protected: + /*! \brief Computes the slope and offset (intercept) of the linear interpolation given two data points. + * + * \detail point1: (_x1, _y1) | point2: (_x2, _y2) + * \f$ slope=\frac{y_2 - y_1}{x_2-x_1}\quad offset=y_2-slope * x_2 \f$ + */ + void BuildLinearInterpolation(const double& _x1, const double& _y1, const double& _x2, const double& _y2, double& _Slope, double& _Offset); + + /*! \brief Doesn't do anything for linear interpolator since there are always only 2 data points. */ + virtual void SetNumberDataPoints(const int& _numberDataPoints) {}; +private: + /** Number of data points used for interpolation, should always be 2 for linear interpolation */ + int m_NumDataPoints; + /** Number of elements in the state vector. Used to determine how many linear interpolations there are per data set. */ + int m_NumElements; + /** Vector of slope parameters. One slope parameter per element. */ + Vector m_Slope; + /** Vector of offset parameters. One slope parameter per element. */ + Vector m_Offset; + Vector m_tempOutput; // this is faster, but larger could be a problem for big histories +}; +} // close namespace O_SESSAME + +#endif + + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: LinearInterpolator.h,v $ +* Revision 1.2 2003/06/06 00:34:47 nilspace +* ? +* +* Revision 1.1 2003/05/13 18:42:08 nilspace +* Initial Submission. +* +* +******************************************************************************/ diff --git a/src/utils/MathUtils.h b/src/utils/MathUtils.h new file mode 100644 index 0000000..c3d7a1f --- /dev/null +++ b/src/utils/MathUtils.h @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file ssfMathUtils.h +* \brief Collection of math constants and utility functions. +* \author $Author: nilspace $ +* \version $Revision: 1.2 $ +* \date $Date: 2003/05/22 03:00:07 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_MATH_UTILS_H__ +#define __SSF_MATH_UTILS_H__ +#include +namespace O_SESSAME { +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \defgroup MathUtils Math Utilities +* \ingroup Utilities +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// +/** @defgroup Trigonometry Trigonometry Routines +* \ingroup MathUtils +* Toolbox of Trigonometry routines useful for spacecraft operations. +* @{ +*/ + +/*! \brief Representation of an angle in radians. + * Currently the angle representation is assumed to be radians, and can be used in any of the other + * Trigonometry functions to convert to Degrees or Degrees-Minutes-Seconds. In the future, the Angle + * should be a class that is unit independent and include the appropriate conversion functions. + */ +typedef double Angle; + +/*! \brief Converts an angle from Degrees, Minutes, Seconds (^o,','') to a single quantity in degrees + * and fractions of a degree. + * @param _Degrees Number of degrees in angle (^o). + * @param _Minutes Number of minutes in angle ('). + * @param _Seconds Number of seconds in angle (''). + * @returns Angle in degrees (with decimal part). + */ +inline double DMS2Deg(const double& _Degrees, const double& _Minutes, const double& _Seconds) +{ + return _Degrees + _Minutes / 60 + _Seconds / 3600; +} + +/*! \brief Converts an angle from a single quantity in degrees + * and fractions of a degree to Degrees, Minutes, Seconds (^o,',''). + * @param _Angle in degrees (with decimal part). + * @param _Degrees Number of degrees in angle (^o). + * @param _Minutes Number of minutes in angle ('). + * @param _Seconds Number of seconds in angle (''). + */ +inline void Deg2DMS(const double& _Angle, double& Degrees, double& Minutes, double& Seconds) +{ + Degrees = floor(_Angle); + Minutes = floor((_Angle - Degrees) * 60); + Seconds = (_Angle - Degrees - Minutes / 60) * 3600; +} + +/*! \brief Converts an angle from Degrees, Minutes, Seconds (^o,','') to radians. + * @param _Degrees Number of degrees in angle (^o). + * @param _Minutes Number of minutes in angle ('). + * @param _Seconds Number of seconds in angle (''). + * @returns Angle in radians (with decimal part). + */ +inline Angle DMS2Rad(const double& _Degrees,const double& _Minutes, const double& _Seconds) +{ + return DMS2Deg(_Degrees, _Minutes, _Seconds) * M_PI / 180; +} + +/*! \brief Converts an angle from Degrees to radians. + * @param _Degrees Angle to be converted (^o). + * @returns Angle in radians (with decimal part). + */ +inline Angle Deg2Rad(const Angle& _Degrees) +{ + return _Degrees * M_PI / 180; +} + +/*! \brief Converts an angle from radians to degrees, minutes, second format. + * @param _Radians Angle to be converted (rad). + * @param Degrees returned number of degrees in angle (^o). + * @param Minutes returned number of minutes in angle ('). + * @param Seconds returned number of seconds in angle (''). + */ +inline void Rad2DMS(const Angle& _Radians, double& Degrees, double& Minutes, double& Seconds) +{ + double Angle = _Radians * 180 / M_PI; + Deg2DMS(Angle, Degrees, Minutes, Seconds); + return; +} + +/*! \brief Converts an angle from radians to degrees. + * @param _Radians The angle to be converted (rad). + * @return returned number of degrees in angle (^o). + */ +inline Angle Rad2Deg(const Angle& _Radians) +{ + return _Radians * 180 / M_PI; +} +/*! \brief Calculates the hyperbolic arctangent of an value using \f$1/2 * log((1+z)/(1-z))$\f. + * @param z value to be calculated. + * @returns hyperbolic arctangent in radians. + */ +inline Angle atanh(const double& _z) +{ + return 0.5 * log((1+_z)/(1-_z)); +} +/** @} */ // end of Trigonometry + + +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: MathUtils.h,v $ +* Revision 1.2 2003/05/22 03:00:07 nilspace +* Updated Angle type and inline'd all functions. +* +* Revision 1.1 2003/05/15 18:32:20 nilspace +* Initial submission. +* +* +******************************************************************************/ diff --git a/src/utils/Plot.cpp b/src/utils/Plot.cpp new file mode 100644 index 0000000..23512df --- /dev/null +++ b/src/utils/Plot.cpp @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Plot.cpp +* \brief Implementation of the Plot class. +* \author $Author: rsharo $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "Plot.h" +namespace O_SESSAME { + +Plot::Plot() +{ + m_pipeVar = popen("gnuplot","w"); + + char tmpname[L_tmpnam]; + m_dataFilename = tmpnam(tmpname); + + return; +} +Plot::~Plot() +{ + // delete data file + pclose(m_pipeVar); // close pipe when you are finished with plotting + return; +} +Plot::Plot(const Matrix &_data) +{ + Plot(); + AddPlot(_data); + return; +} +Plot::Plot(const Matrix &_data, int _cols[], const int &_numCols) +{ + Plot(); + AddPlot(_data, _cols, _numCols); +} + +void Plot::AddPlot(const Matrix &_data) +{ + std::ofstream ofile; + ofile.open(m_dataFilename); + ofile << _data; + ofile.close(); + + fprintf(m_pipeVar, "plot '%s' with linespoints\n", m_dataFilename); + fflush(m_pipeVar); + for(int ii = MatrixIndexBase+2;ii < MatrixIndexBase + _data[MatrixColsIndex].getIndexBound();++ii) + { + fprintf(m_pipeVar, "replot '%s' using 1:%i with linespoints\n", m_dataFilename, ii); + fflush(m_pipeVar); + } + fflush(m_pipeVar); // pipes are buffered, so flush buffer after you are finished + return; +} + +void Plot::AddPlot(const Matrix &_data, int _cols[], const int &_numCols) +{ + for(int ii = 0;ii < _numCols;++ii) + { + fprintf(m_pipeVar, "replot '%s' using 1:%i with linespoints\n", m_dataFilename, ii); + fflush(m_pipeVar); + } + return; +} + +void Plot::Title(const char *_titleString) +{ + fprintf(m_pipeVar, "set title '%s' \n", _titleString); + fflush(m_pipeVar); + return; +} + +void Plot::Set(const char *_parameterName, const char *_values) +{ + return; +} +void Plot::Command(const char *_stringCommand) +{ + return; +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Plot.cpp,v $ +* Revision 1.4 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.3 2003/05/13 18:58:27 nilspace +* Cleaned up comments. +* +* Revision 1.2 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.1 2003/04/08 22:31:25 nilspace +* Initial Submission. +* +* +* +******************************************************************************/ diff --git a/src/utils/Plot.h b/src/utils/Plot.h new file mode 100644 index 0000000..c7a08e4 --- /dev/null +++ b/src/utils/Plot.h @@ -0,0 +1,130 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Plot.h +* \brief Interface to GNUPLOT (http://www.gnuplot.org) +* \author $Author: rsharo $ +* \version $Revision: 1.6 $ +* \date $Date: 2003/10/18 21:37:28 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* \todo figure out if this can be done w/ 1 instance of gnuplot +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __PLOT_H__ +#define __PLOT_H__ +#include +#include +#include +#include "Matrix.h" +namespace O_SESSAME { + +/*! \brief A Plot object is used to display data in a 2-D or 3-D plot. +* \ingroup Utilities +* +* \detail Using GnuPlot, this class is a C++ interface to plotting. +* for a list of GnuPlot commands, visit: http://www.duke.edu/~hpgavin/gnuplot.html or +* http://www.cs.uni.edu/Help/gnuplot/ +* \todo Finish documenting API +*/ +class Plot +{ +public: + Plot(); + virtual ~Plot(); + Plot(const Matrix &_data); + Plot(const Matrix &_data, int _cols[], const int &_numCols); + void AddPlot(const Matrix &_data); + void AddPlot(const Matrix &_data, int _cols[], const int &_numCols); + + void Title(const char *_titleString); + void Set(const char *_parameterName, const char *_values); + void Command(const char *_stringCommand); +private: + FILE* m_pipeVar; + char* m_dataFilename; + +}; + +/** Use GnuPlot to plot the data in a matrix + * @param _data Matrix of data, the first column is x, and each of the other columns will be plotted on the y-axis + */ +static void Plot2D(const Matrix &_data) +{ + FILE* pipeVar; + pipeVar = popen("gnuplot","w"); + std::ofstream ofile; + char tmpname[L_tmpnam]; + char *filename; + filename = tmpnam(tmpname); + ofile.open(filename); + ofile << _data; + ofile.close(); + + fprintf(pipeVar, "plot '%s' with linespoints\n", filename); + fflush(pipeVar); + for(int ii = MatrixIndexBase+2;ii < MatrixIndexBase + _data[MatrixColsIndex].getIndexBound();++ii) + { + fprintf(pipeVar, "replot '%s' using 1:%i with linespoints\n", filename, ii); + fflush(pipeVar); + } + fflush(pipeVar); // pipes are buffered, so flush buffer after you are finished + cout << "Press enter to continue." << flush; + char dummy; + cin >> dummy; + pclose(pipeVar); // close pipe when you are finished with plotting + return; +} + +static void Plot3D(const Matrix &_data) +{ + FILE* pipeVar = popen("gnuplot","w"); + std::ofstream ofile; + + char tmpname[L_tmpnam]; + char *filename; + filename = tmpnam(tmpname); + ofile.open(filename); + ofile << _data; + ofile.close(); + + fprintf(pipeVar, "splot '%s' with lines\n",filename); + fflush(pipeVar); // pipes are buffered, so flush buffer after you are finished + + cout << "Enter a key and press enter to continue..." << flush; + char dummy; + cin >> dummy; + + pclose(pipeVar); // close pipe when you are finished with plotting + return; +} +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Plot.h,v $ +* Revision 1.6 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.5 2003/05/13 18:58:27 nilspace +* Cleaned up comments. +* +* Revision 1.4 2003/05/01 20:28:19 nilspace +* Added stdio.h to includes. +* +* Revision 1.3 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/23 16:28:38 nilspace +* Added functionality to general plot functions. +* +* Revision 1.1 2003/04/08 22:31:25 nilspace +* Initial Submission. +* +* +* +******************************************************************************/ diff --git a/src/utils/RungeKutta.h b/src/utils/RungeKutta.h new file mode 100644 index 0000000..6c22f12 --- /dev/null +++ b/src/utils/RungeKutta.h @@ -0,0 +1,106 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file RungeKutta.h +* \brief Runge-Kutta integrator. +* \author $Author: rsharo $ +* \version $Revision: 1.4 $ +* \date $Date: 2003/10/18 21:37:28 $ +////////////////////////////////////////////////////////////////////////////////////////////////// +* \todo Add test cases +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef RUNGEKUTTA_H +#define RUNGEKUTTA_H + +#include + +/*! defines a pointer to a Runge-Kutta right-hand side (RHS) function */ +typedef Vector(*ptr2RKFunc)(const double &_time, const Vector &_states, const Matrix &_params); + +/** +* Integrate an equation of the form \f$\dot{y} = f\left(t,x\right)\f$ using the Runge-Kutta integration method. +* \detail The Runge-Kutta integrator uses a right-hand side equation, \f$f\left(t,x\right)\f$ to compute the integration of the function over the specified time interval, given initial conditions, constants of integration, and number of steps desired (since this is a fixed step integrator). +* @param odeFunc Pointer to the right-hand side (RHS) equation +* @param timeInput time of current step to RHS file function +* @param stateInput vector of state inputs at current step to RHS file function +* @param constantsInput vector of constants that are not integrated and passed to the RHS function +* @param _initialConditions vector of initial conditions of the state +* @param _constants matrix of constants that should be passed to the RHS function +* @param _timeInitial initial time of integration +* @param _timeFinal final time of integration +* @param _numSteps number of steps to integrate over (therefore timeStep = _timeFinal - _timeInitial / _numSteps) +* @return matrix of integrated state outputs from the initial to final times. Format: +/f[ + \begin{bmatrix} + t_0 & x_{1,0} & x_{2,0} & ...\\ + t_1 & x_{1,1} & x_{2,1} & ...\\ + t_2 & x_{1,2} & x_{2,2} & ...\\ + . & . & . & . \\ + t_final & x_{1,f} & x_{2,f} & ... + \end{bmatrix} +/f] +where /f$t_T/f$ is the time at step T, and /f$x_{i,T}/f$ is the state value of element i, at time step T. +*/ +inline Matrix RungeKuttaSolve(Vector (*odeFunc)(const double &timeInput, const Vector &stateInput, const Matrix &constantsInput), const Vector &_initialConditions, const Matrix &_constants, const double &_timeInitial, const double &_timeFinal, const int &_numSteps) +{ + double h = (_timeFinal - _timeInitial) / _numSteps; + double t = _timeInitial; + int numEqs = _initialConditions.getIndexCount(); + Vector inputs(numEqs); inputs = _initialConditions; + Vector K1(numEqs); + Vector K2(numEqs); + Vector K3(numEqs); + Vector K4(numEqs); + + Matrix output(_numSteps + 1, numEqs + 1); + + output(MatrixIndexBase,MatrixIndexBase) = _timeInitial; + output(MatrixIndexBase,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~_initialConditions; + + Vector temp(numEqs); + for (int ii = 1; ii <= _numSteps; ++ii) + { + K1 = h * odeFunc(t, inputs, _constants); + temp = inputs + K1 / 2.0; + K2 = h * odeFunc(t + h/2, temp, _constants); + temp = inputs + K2 / 2.0; + K3 = h * odeFunc(t + h/2, temp, _constants); + temp = inputs + K3; + K4 = h * odeFunc(t + h, temp, _constants); + for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj) + { + inputs(jj) += (K1(jj) + + 2.0 * K2(jj) + + 2.0 * K3(jj) + + K4(jj)) / 6.0; + } + t = _timeInitial + ii * h; + output(MatrixIndexBase + ii,MatrixIndexBase) = t; + output(MatrixIndexBase + ii,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~inputs; + } + return output; +} + + +#endif /* RungeKutta */ + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: RungeKutta.h,v $ +* Revision 1.4 2003/10/18 21:37:28 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.3 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.2 2003/03/26 16:38:58 nilspace +* Updated comments to better work with Doxygen. +* +* Revision 1.1 2003/03/05 20:41:04 nilspace +* Initial submission of example source code file. +* +* +******************************************************************************/ diff --git a/src/utils/RungeKuttaFehlbergIntegrator.cpp b/src/utils/RungeKuttaFehlbergIntegrator.cpp new file mode 100644 index 0000000..32546b1 --- /dev/null +++ b/src/utils/RungeKuttaFehlbergIntegrator.cpp @@ -0,0 +1,146 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file RungeKuttaFehlbergIntegrator.cpp +* \brief Implementation of the Runge-Kutta-Fehlberg Fourth Order integrator. +* \author $Author: nilspace $ +* \version $Revision: 1.5 $ +* \date $Date: 2003/06/05 20:30:52 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \warning NOT VERIFIED +* \todo Add test cases +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + + +#include "RungeKuttaFehlbergIntegrator.h" +namespace O_SESSAME { + +RungeKuttaFehlbergIntegrator::RungeKuttaFehlbergIntegrator() : m_Tolerance(0.00001), m_minStepSize(0.01), m_maxStepSize(0.25) +{ +} + +Matrix RungeKuttaFehlbergIntegrator::Integrate(const vector& _propTime, odeFunctor _odeFunctorPtr, const Vector& _initialConditions, Orbit* _pOrbit, Attitude* _pAttitude, const Matrix& _constants, const Functor& _functorPtr) +{ + vector::const_iterator timeIterator = _propTime.begin(); + + ssfTime timeInitial = (*timeIterator); + timeIterator = _propTime.end() - 1; + ssfTime timeFinal = (*timeIterator); + ssfTime t = timeInitial; + double h = m_maxStepSize; + double delta; + bool hAccepted = false; + + int numEqs = _initialConditions.getIndexCount(); + Vector inputs = _initialConditions; + Vector tempVector = inputs; + Vector Error(numEqs); + Vector K1(numEqs); + Vector K2(numEqs); + Vector K3(numEqs); + Vector K4(numEqs); + Vector K5(numEqs); + Vector K6(numEqs); + vector output; // state + time + output.reserve(floor((timeFinal-timeInitial) / m_maxStepSize)); + + output.push_back(Vector(numEqs+1)); + output[0](MatrixIndexBase) = timeInitial.GetSeconds(); + output[0](_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = _initialConditions; + + ssfTime tTemp; + Vector temp(numEqs); + int ii = 1; + while (t.GetSeconds() < timeFinal.GetSeconds()) + { + hAccepted = true; + K1 = h * _odeFunctorPtr(t, inputs, _pOrbit, _pAttitude, _constants, _functorPtr); + tTemp = t + h / 4.; temp = inputs + K1 / 4.0; + K2 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + tTemp = t + 3/8. * h; temp = inputs + (3/32. * K1 + 9/32. * K2); + K3 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + tTemp = t + 12/13. * h; temp = inputs + (1932. * K1 - 7200. * K2 + 7296. * K3) / 2197.; + K4 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + tTemp = t + h; temp = inputs + (439/216. * K1 - 8. * K2 +3680/513. * K3 - 845/4104. * K4); + K5 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + tTemp = t + h / 2; temp = inputs - 8/27. * K1 +2. * K2 - 3544/2565. * K3 + 1859/4104. * K4 - 11/40./*0.275*/* K5; + K6 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + + // Check that all the variables are within tolerance + for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj) + { + // If error <= tolerance, calculate integral & output + Error(jj) = 1/h * abs(K1(jj)/360. - 128/4275. * K3(jj) - 2197/75240. * K4(jj) + K5(jj)/50. + K6(jj)/27.5); + +// Could be used for testing +// wTilda = 16/135*K1(jj) + 6656/12825 * K3(jj) + 28561/56430 * K4(jj) - 9/50 * K5(jj) + 2/55*K6(jj); +// w = 25/216 * K1(jj) + 1408/2565 * K3(jj) + 2197/4104 * K4(jj) - 0.2* K5(jj); +// Error(jj) = abs(wTilda - w); + + if((Error(jj) <= m_Tolerance) || (h < m_minStepSize)) + { + tempVector(jj) = inputs(jj) + 25/216. * K1(jj) + 1408/2565. * K3(jj) + 2197/4104. * K4(jj) - 0.2* K5(jj); + } + else + {// if error > tolerance, calc new step size, and re-integrate this step + hAccepted = false; + delta = 0.84 * pow((m_Tolerance / Error(jj)), 0.25); + if(delta <= 0.1) + h = 0.1*h; + else if(delta > 4) + h = 4*h; + else + h = delta * h; + if (h > m_maxStepSize) + h = m_maxStepSize; + break; + } + } + // if all variables are within tolerance, then save output and step forward + if(hAccepted) + { + t = t + h; + inputs = tempVector; + output.push_back(Vector(numEqs+1)); + output[ii](MatrixIndexBase) = t.GetSeconds(); + output[ii](_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = inputs; + ++ii; + + if(t.GetSeconds() + h > timeFinal.GetSeconds()) + h = timeFinal - t; + } + + } + + // Because we used a dynamic vector, we need to move this a Matrix + Matrix outputMatrix(output.size(), numEqs + 1); + + for(ii = 0; ii < output.size(); ++ii) + { + outputMatrix(MatrixIndexBase + ii,_) = ~output[ii](_); + } + return outputMatrix; +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: RungeKuttaFehlbergIntegrator.cpp,v $ +* Revision 1.5 2003/06/05 20:30:52 nilspace +* Removed testing cout commands. +* +* Revision 1.4 2003/06/05 20:09:14 nilspace +* Finished implementation and verified against a short 2 second integration. +* +* Revision 1.3 2003/05/22 02:59:15 nilspace +* Updated comments. Changed to pass in pointers to Orbit & Attitude objects. +* +* Revision 1.2 2003/04/25 13:45:55 nilspace +* const'd Get() functions. +* +* Revision 1.1 2003/04/23 15:08:28 nilspace +* Initial submission of RKF integrator. +* +* +******************************************************************************/ + + diff --git a/src/utils/RungeKuttaFehlbergIntegrator.h b/src/utils/RungeKuttaFehlbergIntegrator.h new file mode 100644 index 0000000..e817417 --- /dev/null +++ b/src/utils/RungeKuttaFehlbergIntegrator.h @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*!\file RungeKuttaFehlbergIntegrator.h +* \brief Runge-Kutta-Fehlberg integrator. +* \author $Author: nilspace $ +* \version $Revision: 1.5 $ +* \date $Date: 2003/06/05 20:09:14 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* \todo Add test cases +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_RUNGEKUTTAFEHLBERG_INTEGRATOR_H__ +#define __SSF_RUNGEKUTTAFEHLBERG_INTEGRATOR_H__ + +#include "Matrix.h" +#include "Integrator.h" +namespace O_SESSAME { +/*! \brief Runge-Kutta-Fehlberg integrator +* \ingroup IntegrationLibrary +* +* \warning Implementation not complete! +* \todo document algorithm +*/ +class RungeKuttaFehlbergIntegrator : public Integrator +{ +public: + RungeKuttaFehlbergIntegrator(); + + /*! Specific Orbit/Attitude simulation integration function + * + */ + Matrix Integrate(const vector& _propTime, odeFunctor _odeFunctorPtr, const Vector& _initialConditions, Orbit* _pOrbit, Attitude* _pAttitude, const Matrix& _constants, const Functor& _functorPtr); + + /*! \brief Set the tolerance of the integration. + * @param _numSteps number of steps to include between integration timesteps + */ + void SetTolerance(const double& _Tolerance) { m_Tolerance = _Tolerance; return; } + + /*! \brief Return the tolerance of the integration + * @return tolerance of the integration + */ + double GetTolerance() { return m_Tolerance; } + + /*! \brief Set the minimum and maximum step-sizes. + * @param _minStepSize minimum step-size between integration meshpoints. + * @param _maxStepSize maximum step-size between integration meshpoints. + */ + void SetStepSizes(const double& _minStepSize, const double& _maxStepSize) { m_minStepSize = _minStepSize; m_maxStepSize = _maxStepSize; return; } + +private: + double m_Tolerance; /*!< Desired tolerance of the integration between timesteps */ + double m_minStepSize; /*!< minimum step-size between integration calculation meshpoints */ + double m_maxStepSize; /*!< maximum step-size between integration calculation meshpoints */ +}; +} // close namespace O_SESSAME + +#endif +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: RungeKuttaFehlbergIntegrator.h,v $ +* Revision 1.5 2003/06/05 20:09:14 nilspace +* Finished implementation and verified against a short 2 second integration. +* +* Revision 1.4 2003/05/22 02:59:15 nilspace +* Updated comments. Changed to pass in pointers to Orbit & Attitude objects. +* +* Revision 1.3 2003/05/13 18:58:27 nilspace +* Cleaned up comments. +* +* Revision 1.2 2003/04/25 13:45:55 nilspace +* const'd Get() functions. +* +* Revision 1.1 2003/04/23 15:08:28 nilspace +* Initial submission of RKF integrator. +* +* +******************************************************************************/ diff --git a/src/utils/RungeKuttaIntegrator.cpp b/src/utils/RungeKuttaIntegrator.cpp new file mode 100644 index 0000000..01bc53e --- /dev/null +++ b/src/utils/RungeKuttaIntegrator.cpp @@ -0,0 +1,179 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file RungeKuttaIntegrator.cpp +* \brief Implementation of the Runge-Kutta Fourth Order integrator. +* \author $Author: nilspace $ +* \version $Revision: 1.7 $ +* \date $Date: 2003/05/22 02:59:15 $ +////////////////////////////////////////////////////////////////////////////////////////////////// +* \todo Add test cases +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + + +#include "RungeKuttaIntegrator.h" +namespace O_SESSAME { + +/*! \brief Creates a default, unitialized RK-integrator. + */ +RungeKuttaIntegrator::RungeKuttaIntegrator() +{ + m_NumSteps = 1; +} + +/** \todo pull out RungeKuttaIntegrator::Step function */ +/* +Matrix RungeKuttaIntegrator::Integrate(const Vector &_propTime, odeFunc _FuncPtr, const Vector &_initialConditions, const Matrix &_constants, vectorFuncPtr _vectorFuncPtr) +{ + double timeInitial = _propTime(VectorIndexBase); + double t = timeInitial; + double h = (_propTime(VectorIndexBase + 1) - t) / m_NumSteps; + + int numEqs = _initialConditions.getIndexCount(); + Vector inputs = _initialConditions; + Vector K1(numEqs); + Vector K2(numEqs); + Vector K3(numEqs); + Vector K4(numEqs); + + Matrix output(m_NumSteps + 1, numEqs + 1); + + output(MatrixIndexBase,MatrixIndexBase) = timeInitial; + output(MatrixIndexBase,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~_initialConditions; + + Vector temp(numEqs); + for (int ii = 1; ii <= m_NumSteps; ++ii) + { + K1 = h * _FuncPtr(t, inputs, _constants, _vectorFuncPtr); + temp = inputs + K1 / 2.0; + K2 = h * _FuncPtr(t + h/2, temp, _constants, _vectorFuncPtr); + temp = inputs + K2 / 2.0; + K3 = h * _FuncPtr(t + h/2, temp, _constants, _vectorFuncPtr); + temp = inputs + K3; + K4 = h * _FuncPtr(t + h, temp, _constants, _vectorFuncPtr); + for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj) + { + inputs(jj) += (K1(jj) + + 2.0 * K2(jj) + + 2.0 * K3(jj) + + K4(jj)) / 6.0; + } + t = timeInitial + ii * h; + output(MatrixIndexBase + ii,MatrixIndexBase) = t; + output(MatrixIndexBase + ii,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~inputs; + } + return output; +} +*/ + + /*! \brief Integrates the Right-Hand Side (RHS) equation using a Runge-Kutta 4th Order %integrator. + * + * This function will integrate an equation of the form \f$\dot{\bf x} = f(t,{\bf x})\f$ from \f$t_0\f$ to \f$t_f\f$ given + * initial conditions, an orbit and attitude object (or empty references if not required), a matrix of constants, and an + * external call-back function. + * + * @param _propTime This input variable specifies the list of integration times, from the starting value (first time) to the ending integration (last time) with the specified intervals. + * If no specific intervals are required (and can be interpolated later), the user needs to just specify the beginning and end times of integration. + * This vector is built by creating ssfTime object, and "push_back" them onto the vector list: + * \code + * vector integrationTimes; + * ssfTime begin(0); + * ssfTime end(begin + 20); + * integrationTimes.push_back(begin); + * integrationTimes.push_back(end); + * \endcode + * @param _FunctorPtr This is the reference (odeFunctor) to the Right-Hand side (RHS) of the integration equation. It should be a single function that computes the time derivative + * of the state given the time, current state, and other parameters. + * @param _initialConditions The vector of initial conditions of the state being integrated. It can be any sized. + * @param _pOrbit This is a pointer to an Orbit object. It will be passed directly to the RHS and may be used for evaluating the dynamics or disturbance torque/forces. + * However, if no orbit is required, or used, the user should only pass a NULL pointer and the orbit object shouldn't be used in the user's RHS function. + * @param _pAttitude This is a pointer to an Attitude object. It behaves much the same way as _Orbit above. It will be passed directly to the RHS function for use in + * evaluation, but if not used, the user should only pass a NULL pointer, and the attitude object not used in the RHS function. + * @param _constants This is a matrix of constants that is required by the RHS function. The constants are passed to each evaluation of the RHS, and may be any size, and + * store any values the user requires. Examples include Moments of Inertia, ballistic coefficients, mass, etc. + * @param _functorPtr The Functor is a call-back function that the RHS can use to evaluate an external function call. The prototype of the _functorPtr must correspond to the Functor + * definition, but other than that, may perform any calculations required by the user in the RHS function. + * @return The output of the integration function is a matrix of calculated integration times (meshpoints), and integrated state values at each of the meshpoints. + * \f[ + * \begin{bmatrix} + * t_0 & x_{1,0} & x_{2,0} & ...\\ + * t_1 & x_{1,1} & x_{2,1} & ...\\ + * t_2 & x_{1,2} & x_{2,2} & ...\\ + * . & . & . & . \\ + * t_{final} & x_{1,f} & x_{2,f} & ... + * \end{bmatrix} + * \f] + * where /f$t_T/f$ is the time at step T, and /f$x_{i,T}/f$ is the state value of element i, at time step T. + */ +Matrix RungeKuttaIntegrator::Integrate(const vector& _propTime, odeFunctor _odeFunctorPtr, const Vector& _initialConditions, Orbit* _pOrbit, Attitude* _pAttitude, const Matrix& _constants, const Functor& _functorPtr) +{ + vector propTime = _propTime; // need to create copy to prevent the stl .begin() and .end() from discarding the const-ness + vector::iterator timeIterator = propTime.begin(); + + ssfTime timeInitial = (*timeIterator); + ssfTime t = timeInitial; + timeIterator = propTime.end() - 1; + double h = ((*timeIterator).GetSeconds() - timeInitial.GetSeconds()) / m_NumSteps; // Calculation step size (seconds) + int numEqs = _initialConditions.getIndexCount(); + Vector inputs = _initialConditions; + Vector K1(numEqs); + Vector K2(numEqs); + Vector K3(numEqs); + Vector K4(numEqs); + + Matrix output(m_NumSteps + 1, numEqs + 1); + + output(MatrixIndexBase,MatrixIndexBase) = timeInitial.GetSeconds(); + output(MatrixIndexBase,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~_initialConditions; + ssfTime tTemp; + Vector temp(numEqs); + for (int ii = 1; ii <= m_NumSteps; ++ii) + { + K1 = h * _odeFunctorPtr(t, inputs, _pOrbit, _pAttitude, _constants, _functorPtr); + temp = inputs + K1 / 2.0; tTemp = t + h/2; + K2 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + temp = inputs + K2 / 2.0; + K3 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + temp = inputs + K3; tTemp = t + h; + K4 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr); + for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj) + { + inputs(jj) += (K1(jj) + + 2.0 * K2(jj) + + 2.0 * K3(jj) + + K4(jj)) / 6.0; + } + t = timeInitial + ii * h; + output(MatrixIndexBase + ii,MatrixIndexBase) = t.GetSeconds(); + output(MatrixIndexBase + ii,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~inputs; + } + return output; +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: RungeKuttaIntegrator.cpp,v $ +* Revision 1.7 2003/05/22 02:59:15 nilspace +* Updated comments. Changed to pass in pointers to Orbit & Attitude objects. +* +* Revision 1.6 2003/05/13 18:58:27 nilspace +* Cleaned up comments. +* +* Revision 1.5 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.4 2003/04/25 14:15:06 nilspace +* Created a temporary vectro to prevent the STL .begin() and .end() functions from discarding the const-ness of _propTime in Integrate(). +* +* Revision 1.3 2003/04/25 13:45:55 nilspace +* const'd Get() functions. +* +* Revision 1.2 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:29:55 nilspace +* Initial submission. Made a subclass of Integrator. +* +* +* +******************************************************************************/ diff --git a/src/utils/RungeKuttaIntegrator.h b/src/utils/RungeKuttaIntegrator.h new file mode 100644 index 0000000..ac31197 --- /dev/null +++ b/src/utils/RungeKuttaIntegrator.h @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*!\file RungeKuttaIntegrator.h +* \brief Runge-Kutta integrator. +* \author $Author: nilspace $ +* \version $Revision: 1.8 $ +* \date $Date: 2003/05/22 02:59:15 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Add test cases +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_RUNGEKUTTA_INTEGRATOR_H__ +#define __SSF_RUNGEKUTTA_INTEGRATOR_H__ + +#include "Matrix.h" +#include "Integrator.h" +namespace O_SESSAME { + +/*! \class RungeKuttaIntegrator +* \brief Implementation of a Runge-Kutta (Fourth Order) %Integrator. +* \ingroup IntegrationLibrary +* +* \copydoc Integrator +* \todo document algorithm +* \example testAttitudeIntegration.cpp +* \example testOrbitIntegration.cpp +*/ +class RungeKuttaIntegrator : public Integrator +{ +public: + RungeKuttaIntegrator(); + + Matrix Integrate(const vector& _propTime, odeFunctor _odeFunctorPtr, const Vector& _initialConditions, Orbit* _Orbit, Attitude* _Attitude, const Matrix& _constants, const Functor& _functorPtr); + + /*! Standard Integration Function */ +// Matrix Integrate(const Vector &_propTime, odeFunc _FuncPtr, const Vector &_initialConditions, const Matrix &_constants, vectorFuncPtr _vectorFuncPtr); + + /*! \brief Set the number of integration steps + * @param _numSteps number of steps to include between integration timesteps + */ + void SetNumSteps(const int &_numSteps) { m_NumSteps = _numSteps; return; } + + /*! \brief Return the number of integration steps + * @return current number of integration steps performed b/w every timestep + */ + int GetNumSteps() { return m_NumSteps; } +private: + int m_NumSteps; /*!< \brief number of integration steps performed b/w every timestep */ +}; +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: RungeKuttaIntegrator.h,v $ +* Revision 1.8 2003/05/22 02:59:15 nilspace +* Updated comments. Changed to pass in pointers to Orbit & Attitude objects. +* +* Revision 1.7 2003/05/21 19:52:47 nilspace +* Updated comments. +* +* Revision 1.6 2003/05/20 17:44:21 nilspace +* Updated comments. +* +* Revision 1.5 2003/05/13 18:58:27 nilspace +* Cleaned up comments. +* +* Revision 1.4 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.3 2003/04/25 13:45:55 nilspace +* const'd Get() functions. +* +* Revision 1.2 2003/04/23 16:30:59 nilspace +* Various bugfixes & uploading of all changed code for new programmers. +* +* Revision 1.1 2003/04/08 22:29:55 nilspace +* Initial submission. Made a subclass of Integrator. +* +******************************************************************************/ diff --git a/src/utils/Time.cpp b/src/utils/Time.cpp new file mode 100644 index 0000000..b7197ea --- /dev/null +++ b/src/utils/Time.cpp @@ -0,0 +1,195 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Time.h +* \brief Implementation of the Time class. +* \author $Author: rsharo $ +* \version $Revision: 1.10 $ +* \date $Date: 2003/10/18 22:02:11 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* +* \todo Finish implementing the rest of the time representatins. +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "utils/Time.h" + +namespace O_SESSAME { + +static int DaysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +/*! \brief Calculates the Julian Date given a time in seconds since the system epoch. + * \ingroup TimeUtils + * \relates ssfTime + * This function takes in seconds since epoch and returns the datetime in Julian Date + * format. Since the input time is seconds since system epoch (Jan 1, 1970 at midnight for + * linux), the JulianDate function uses the system gmtime() function to convert to a DateTime + * struct. + * \warning be careful of differences in system epoch times (Unix vs. Windows). + * @param _time The time to be converted in seconds since the system epoch time. + * @return this function returns the conversion from seconds since system epoch time to + * Julian Date. + */ +ssfJulianDate JulianDate(const ssfSeconds &_time) +{ + time_t t = static_cast(floor(_time)); + tm DateTime = *gmtime(&t); + ssfJulianDate JD = 0; + double uSec = _time - floor(_time); + JD += 367 * (DateTime.tm_year + 1900); + JD -= floor((7 * ((DateTime.tm_year + 1900) + floor(((DateTime.tm_mon + 1) + 9)/12))) / 4); + JD += floor((275 * (DateTime.tm_mon + 1)) / 9); + JD += DateTime.tm_mday; + JD += 1721013.5; + JD += (((DateTime.tm_sec + uSec)/60.0 + DateTime.tm_min) / 60.0 + DateTime.tm_hour) / 24; + return JD; +} + +void DayofYear2YMD(int _dayOfYear, int _year, int &_month, int &_day) +{ + int total = 0; + // Is it a leap-year? + if (_year % 4 == 0) + DaysInMonth[1] = 29; + for (_month = 0; total + DaysInMonth[_month+1] < _dayOfYear; ++_month) + { + total += DaysInMonth[_month]; + } + ++_month; + _day = _dayOfYear - total; + return; +} + +/*! \fn ssfJulianDate ssfTime::GetJulianDate() const +* +/f[ +\mbox{Julian Date} & = & 367(year) - floor\left(\frac{7\left[year+floor\left(\frac{month+9}{12}\right)\right]}{4}\right) \\ +& & + floor\left(\frac{275month}{9}\right) + day + 1,721,013.5\\ +& & + \frac{\frac{\left(\frac{seconds}{60} + minute\right)}{60}+hour}{24} +/f] +*/ +ssfJulianDate ssfTime::GetJulianDate() const +{ +/* + time_t t = static_cast(floor(m_StoredTime)); + tm DateTime = *gmtime(&t); + ssfJulianDate JD = 0; + double uSec = m_StoredTime - floor(m_StoredTime); + JD += 367 * (DateTime.tm_year + 1900); + JD -= floor((7 * ((DateTime.tm_year + 1900) + floor(((DateTime.tm_mon + 1) + 9)/12))) / 4); + JD += floor((275 * (DateTime.tm_mon + 1)) / 9); + JD += DateTime.tm_mday; + JD += 1721013.5; + JD += (((DateTime.tm_sec + uSec)/60.0 + DateTime.tm_min) / 60.0 + DateTime.tm_hour) / 24; + return JD; +*/ + return JulianDate(m_StoredTime); +} + +ssfJulianDate ssfTime::GetEpochJulianDate() const +{ + return JulianDate(m_EpochTime); +} +void ssfTime::Set(int year, int month, int day, int hour, int minute, double seconds) +{ + tm DateTime; + DateTime.tm_year = year - 1900; + DateTime.tm_mon = month - 1; + DateTime.tm_mday = day; + DateTime.tm_hour = hour; + DateTime.tm_min = minute; + DateTime.tm_sec = static_cast(floor(seconds)); + m_StoredTime = static_cast(timegm(&DateTime)); + m_StoredTime += seconds - floor(seconds); +} + +void ssfTime::SetEpoch(int year, int month, int day, int hour, int minute, double seconds) +{ + tm DateTime; + DateTime.tm_year = year - 1900; + DateTime.tm_mon = month - 1; + DateTime.tm_mday = day; + DateTime.tm_hour = hour; + DateTime.tm_min = minute; + DateTime.tm_sec = static_cast(floor(seconds)); + m_EpochTime = static_cast(timegm(&DateTime)); + m_EpochTime += seconds - floor(seconds); +} + + +void ssfTime::SetJulianDate(ssfJulianDate _newJD) +{ + // Since the Julian Date is measured in days, while the + // internal time is stored in seconds since the system epoch, + // subtract the system Julian Date from the specified + // Julian Date and convert to seconds. + m_StoredTime = (_newJD - JulianDate(0)) * 24 * 60 * 60; + return; +} + +void ssfTime::SetEpochJulianDate(ssfJulianDate _newJD) +{ + // Since the Julian Date is measured in days, while the + // internal time is stored in seconds since the system epoch, + // subtract the system Julian Date from the specified + // Julian Date and convert to seconds. + m_EpochTime = (_newJD - JulianDate(0)) * 24 * 60 * 60; + return; +} + +Angle ssfTime::GetGreenwichMeanSiderealTime() const +{ + double Tut1 = (this->GetJulianDate() - c_GreenwichSiderealEpochTime.GetJulianDate() - 2451545) / 36525; + return 1.753368560 + 628.3319706889*Tut1 + 6.7707*pow(10,-6)*pow(Tut1,2) - 4.5*pow(10,-10)*pow(Tut1,3); +} + +Angle ssfTime::GetEpochGreenwichMeanSiderealTime() const +{ + double Tut1 = (this->GetEpochJulianDate() - c_GreenwichSiderealEpochTime.GetJulianDate() - 2451545) / 36525; + return 1.753368560 + 628.3319706889*Tut1 + 6.7707*pow(10,-6)*pow(Tut1,2) - 4.5*pow(10,-10)*pow(Tut1,3); +} + +std::ostream & operator << (std::ostream& s, ssfTime& t) +{ + s << std::setprecision(TIME_PRECISION) << t.GetSeconds(); + return s; +} +} // close namespace O_SESSAME + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Time.cpp,v $ +* Revision 1.10 2003/10/18 22:02:11 rsharo +* Fixed CR-LF problem. +* +* Revision 1.9 2003/10/18 21:37:29 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.8 2003/06/10 14:49:16 nilspace +* removed commas from numbers. +* +* Revision 1.7 2003/06/10 01:11:46 nilspace +* Fixed Time to build correctly (changed Greenwich epoch time to object instead of pointer) +* +* Revision 1.6 2003/06/09 19:41:30 nilspace +* Added SetEpoch(year,month,day,hour,minute,second) +* +* Revision 1.5 2003/05/21 13:35:59 nilspace +* Fixed the second GetJulianDate to be GetEpochJulianDate +* +* Revision 1.4 2003/05/21 03:57:52 nilspace +* Added GetEpochJulianDate and comments to JulianDate conversion function. +* +* Revision 1.3 2003/05/20 17:44:21 nilspace +* Updated comments. +* +* Revision 1.2 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.1 2003/04/23 14:46:49 nilspace +* New Time class for simulation time. +* +* +******************************************************************************/ + diff --git a/src/utils/Time.h b/src/utils/Time.h new file mode 100644 index 0000000..ba117ad --- /dev/null +++ b/src/utils/Time.h @@ -0,0 +1,525 @@ +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \file Time.h +* \brief Encapsulation of the Time object, the global time instance, and time functions. +* \author $Author: rsharo $ +* \version $Revision: 1.15 $ +* \date $Date: 2003/10/18 21:54:44 $ +*////////////////////////////////////////////////////////////////////////////////////////////////// +/* \todo Finish implementing the rest of the time representatins. +*/ +////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __SSF_TIME_H__ +#define __SSF_TIME_H__ +#include +#include +#include +#include +#include + +#include "MathUtils.h" + +// +// If didn't define timegm()... +#if !defined(timegm) +// +// ... Then declare a function that emulates timegm(). This function doesn't +// have public documentation (doxygen) because we don't want anybody to call +// it explicitly. When people call timegm(), we'll redefine it as a +// mktime_from_utc() call only where necessary. +time_t mktime_from_utc(struct tm *t); +#define timegm(T) mktime_from_utc(T) +#endif + +namespace O_SESSAME { +////////////////////////////////////////////////////////////////////////////////////////////////// +/*! @defgroup Utilies Utilities +* The Utilities are the collection of classes and function that can provide miscellaneous functionality +* to assist with the spacecraft simulation. This includes a time object, plotting, timing of execution +* speed, interface to lower-level software and operating system components and general math functions. +* +* \par Extension Points: +* Any other operating system calls should be encapsulated in a utility class/function to +* ease the use of the tool/call and help promote cross-platform compatability. This may include +* file storage and retrieval functions, communications protocols, or database interoperability. +*/ + +/*! @defgroup TimeUtils Time Utilities +* \ingroup Utilities +* @{ +*/ +typedef double ssfSeconds; /*< Simulation representation of seconds \ingroup Utilities*/ +typedef double ssfJulianDate; /*< Simulation representation of Julian Dates \ingroup Utilities */ + +#define TIME_PRECISION 15 /*< Precision of time output when outputting seconds */ +/*! @} */ + +class ssfTime; + +/*! \brief Simulation Time object +* \ingroup TimeUtils +* +* ssfTime is used to encapsulate a representation of time and provide the +* functionality for converting between different time representations (ie +* Mean Solar, Sidereal, Julian Date, etc.) The ssfTime object includes both +* a stored time, as well as an epoch that the time can be measured from. +* \par Example: +* \code +* ssfTime simTime; +* ssfSeconds integrationTime = 10; +* simTime.Set(integrationTime); +* +* ssfTime nowTime(Now()); +* \endcode +*/ +class ssfTime +{ +public: + /*! \brief Default constructor. Initializes the time to 0 seconds. */ + ssfTime() + {Set(ssfSeconds(0)); SetEpoch(ssfSeconds(0));}; + /*! \brief Constructor creates a time object as a copy of a time struct. + * @param _Time tm struct to be copied as the time object. + */ + ssfTime(tm _Time) + {Set(_Time);}; + /*! \brief Constructor creates a time object as a copy of a timeval struct. + * + * + *struct timeval { + * long tv_sec; // seconds + * long tv_usec; // and microseconds + * }; + * @param _Time timeval struct to be copied as the time object. + */ + ssfTime(timeval _Time) + {Set(_Time);}; + /*! \brief Constructor creates time object based on number of seconds. + * @param _Time number of seconds to set the time object to. + */ + ssfTime(ssfSeconds _Time) + {Set(_Time);}; + + /*! \brief Constructor creates time object based on a calendar date. + * @param year 4-digit year (must be between 1900-2100) + * @param month numeric month (1-12) + * @param day day of the month (1-31) + * @param hour hour in 24-hour format (0-23) + * @param minute minutes of the hour (0-59) + * @param seconds seconds of the minute (0-59.9999999999) + */ + ssfTime(int year, int month, int day, int hour, int minute, double seconds) + {Set(year, month, day, hour, minute, seconds);}; + + /*! \brief Set the ssfTime object to a specified time struct. + * @param _newTime the time to store in a tm struct + */ + void Set(tm _newTime) + {Set(static_cast(timegm(&_newTime)));}; + + /*! \brief Set the time object as a copy of a timeval struct. + * + * + * struct timeval { + * long tv_sec; // seconds + * long tv_usec; // and microseconds + * }; + * @param _Time timeval struct to set the time object. + */ + void Set(timeval _Time) + {Set(_Time.tv_sec + _Time.tv_usec/1000000.);}; + + /*! \brief Set the ssfTime object to a specified time in seconds. + * + * @param _newTime the time to store + */ + void Set(ssfSeconds _newTime) + {m_StoredTime = _newTime;}; + + /*! \brief Set the ssfTime object to a specified Julian Date. + * @param _newJD Julian Date to set. + */ + void SetJulianDate(ssfJulianDate _newJD); + + /*! \brief Set the Epoch to a specified Julian Date. + * @param _newJD Julian Date to set. + */ + void SetEpochJulianDate(ssfJulianDate _newJD); + + /*! \brief Set the ssfTime object based on a calendar date. + * @param year 4-digit year (must be between 1900-2100) + * @param month numeric month (1-12) + * @param day day of the month (1-31) + * @param hour hour in 24-hour format (0-23) + * @param minute minutes of the hour (0-59) + * @param seconds seconds of the minute (0-59.9999999999) + */ + void Set(int year, int month, int day, int hour, int minute, double seconds); + + /*! \brief Set the current time after epoch. + * @param _timeAfter time (in seconds) after epoch + */ + void SetTimeAfterEpoch(ssfSeconds _timeAfter) + {Set(m_EpochTime + _timeAfter);}; + + /*! \brief Set the epoch time + * @param _newEpochTime new Epoch (seconds) + */ + void SetEpoch(ssfSeconds _newEpochTime) + {m_EpochTime = _newEpochTime;}; + + /*! \brief Set the epoch time + * @param _newEpochTime new Epoch (tm struct) + */ + void SetEpoch(tm _newEpochTime) + {SetEpoch(static_cast(timegm(&_newEpochTime)));}; + + /*! \brief Set the epoch time from a timeval struct. + * + * + * struct timeval { + * long tv_sec; // seconds + * long tv_usec; // and microseconds + * }; + * @param _Time timeval struct used to set the Epoch time. + */ + void SetEpoch(const timeval &_Time) + {SetEpoch(_Time.tv_sec + _Time.tv_usec/1000000.);}; + + /*! \brief Set the epoch of the ssfTime object based on a calendar date. + * @param year 4-digit year (must be between 1900-2100) + * @param month numeric month (1-12) + * @param day day of the month (1-31) + * @param hour hour in 24-hour format (0-23) + * @param minute minutes of the hour (0-59) + * @param seconds seconds of the minute (0-59.9999999999) + */ + void SetEpoch(int year, int month, int day, int hour, int minute, double seconds); + + /*! \brief Return the current time in seconds + * @return currently stored time (seconds) + */ + ssfSeconds GetSeconds() const + {return m_StoredTime;}; + + /*! \brief Return a tm struct of the date, time of the stored time. + * @return tm struct of the date-time + * @em tm Struct Definition: + \code + * int tm_sec; // seconds (0 - 60) + * int tm_min; // minutes (0 - 59) + * int tm_hour; // hours (0 - 23) + * int tm_mday; // day of month (1 - 31) + * int tm_mon; // month of year (0 - 11) + * int tm_year; // year - 1900 + * int tm_wday; // day of week (Sunday = 0) + * int tm_yday; // day of year (0 - 365) + * int tm_isdst; // is summer time in effect? + * char *tm_zone; // abbreviation of timezone name + * long tm_gmtoff; // offset from UTC in seconds + \endcode + * \par Example: + * \code + * cout << myTime.GetDateTime().tm_mon << "/" << myTime.GetEpochDateTime().tm_mday << "/" << myTime.GetEpochDateTime().tm_year; + * \endcode + * \warning does not return sub-seconds (rounded to lowest second) + */ + tm GetDateTime() const + {time_t t = static_cast(floor(m_StoredTime));return *gmtime(&t);}; + + /*! \brief Return the epoch in a tm struct of the date-time . + * @return tm struct of the date-time. + * + * @em tm Struct Definition: + \code + * int tm_sec; // seconds (0 - 60) + * int tm_min; // minutes (0 - 59) + * int tm_hour; // hours (0 - 23) + * int tm_mday; // day of month (1 - 31) + * int tm_mon; // month of year (0 - 11) + * int tm_year; // year - 1900 + * int tm_wday; // day of week (Sunday = 0) + * int tm_yday; // day of year (0 - 365) + * int tm_isdst; // is summer time in effect? + * char *tm_zone; // abbreviation of timezone name + * long tm_gmtoff; // offset from UTC in seconds + \endcode + * \par Example: + * \code + * cout << myTime.GetEpochDateTime().tm_mon << "/" << myTime.GetEpochDateTime().tm_mday << "/" << myTime.GetEpochDateTime().tm_year; + * \endcode + * \warning does not return sub-seconds (rounded to lowest second) + */ + tm GetEpochDateTime() const + {time_t t = static_cast(floor(m_EpochTime));return *gmtime(&t);}; + + /*! \brief Return the current Epoch + * @return currently stored epoch time (tm struct) + */ + ssfSeconds GetEpoch() const + {return m_EpochTime;}; + + + /*! \brief Get the Julian Date of the time object. + * @return This function returns the Julian Date (DETAIL JD OUTPUT) + */ + ssfJulianDate GetJulianDate() const; + + /*! \brief Get the Julian Date of the time object's epoch. + * @return This function returns the Epoch in Julian Date format (DETAIL JD OUTPUT) + */ + ssfJulianDate GetEpochJulianDate() const; + + + /*! \brief Calculate the Greenwich sidereal time of the stored time. + * @return Greenwich sidereal time, measured from epoch in 1970, [rad] + */ + Angle GetGreenwichMeanSiderealTime() const; + + /*! \brief Get the Julian Date of the time object's epoch. + * + * ref Vallado p.61-63 + * \warning need to change to accept different epochs & account for rotation of central body + * @return Greenwich sidereal time of the epoch, measured from epoch in 1970, [rad] + */ + Angle GetEpochGreenwichMeanSiderealTime() const; + + /*! \brief Return the current Epoch + * + * ref Vallado p.61-63 + * \warning need to change to accept different epochs & account for rotation of central body + * @return currently stored epoch time (tm struct) + */ +// tm GetEpoch() const + // {return *gmtime(&m_EpochTime);}; + + /*! \brief Return the time since epoch + * @return the number of seconds that have passed since epoch + */ + ssfSeconds SecondsSinceEpoch() const + {return static_cast(m_StoredTime - m_EpochTime);}; + + /*! \brief Add specified number of seconds to the current time and return a new object. + * @param rhsSeconds Number of seconds to be added. + * @return new Time object whose current time is equal to the original time plus rhsSeconds. + */ + ssfTime operator+ (const int& rhsSeconds) const + {return operator+(static_cast(rhsSeconds));}; + + /*! \brief Add specified number of seconds to the current time. + * @param rhsSeconds Number of seconds to be added. + * @return the same time object with the current time plus rhsSeconds. + */ + ssfTime operator+= (const int& rhsSeconds) + {return operator+=(static_cast(rhsSeconds));}; + + /*! \brief Add specified number of seconds to the current time and return a new object. + * @param rhsSeconds Number of seconds to be added. + * @return new Time object whose current time is equal to the original time plus rhsSeconds. + */ + ssfTime operator+ (const long& rhsSeconds) const + {return operator+(static_cast(rhsSeconds));}; + + /*! \brief Add specified number of seconds to the current time. + * @param rhsSeconds Number of seconds to be added. + * @return the same time object with the current time plus rhsSeconds. + */ + ssfTime operator+= (const long& rhsSeconds) + {return operator+=(static_cast(rhsSeconds));}; + + /*! \brief Add specified number of seconds to the current time and return a new object. + * @param rhsSeconds Number of seconds to be added. + * @return new Time object whose current time is equal to the original time plus rhsSeconds. + */ + ssfTime operator+ (const ssfSeconds& rhsSeconds) const + {return ssfTime(m_StoredTime + rhsSeconds);}; + + /*! \brief Add specified number of seconds to the current time. + * @param rhsSeconds Number of seconds to be added. + * @return the same time object with the current time plus rhsSeconds. + */ + ssfTime operator+= (const ssfSeconds& rhsSeconds) + {m_StoredTime += rhsSeconds; return *this;}; + + /*! \brief Subtract two time objects (the stored times). + * @param rhs time object to be subtracted. + * @return new time object that is the difference between the lhs and the rhs. + */ + ssfSeconds operator- (const ssfTime &rhs) const + {return (m_StoredTime - rhs.GetSeconds());}; + + /*! \brief Greater than comparison two time objects (the stored times). + * @param rhs time object to be compared with. + * @return TRUE if the left operand's stored time is greater than the right operand's stored time, FALSE if it is not. + */ + bool operator> (const ssfTime &rhs) const + {return (m_StoredTime > rhs.GetSeconds());}; + + /*! \brief Greater than or equal comparison two time objects (the stored times). + * @param rhs time object to be compared with. + * @return TRUE if the left operand's stored time is greater than or equal to the right operand's stored time, FALSE if it is not. + */ + bool operator>= (const ssfTime &rhs) const + {return (m_StoredTime >= rhs.GetSeconds());}; + + /*! \brief Less than comparison two time objects (the stored times). + * @param rhs time object to be compared with. + * @return TRUE if the left operand's stored time is less than the right operand's stored time, FALSE if it is not. + */ + bool operator< (const ssfTime &rhs) const + {return (m_StoredTime < rhs.GetSeconds());}; + + /*! \brief Less than or equal comparison two time objects (the stored times). + * @param rhs time object to be compared with. + * @return TRUE if the left operand's stored time is Less than or equal to the right operand's stored time, FALSE if it is not. + */ + bool operator<= (const ssfTime &rhs) const + {return (m_StoredTime <= rhs.GetSeconds());}; + + /*! \brief Compare the equality of two time objects (the stored times). + * @param rhs time object to be compared with. + * @return TRUE if the stored times are equal, FALSE if they are not. + * \todo Determine if it needs to compare the Epoch times as well. + */ + bool operator== (const ssfTime &rhs) const + {return (m_StoredTime == rhs.GetSeconds());}; + + /*! \brief Compare the inequality of two time objects (the stored times). + * @param rhs time object to be compared with. + * @return TRUE if the stored times are not equal, FALSE if they are equal. + * \todo Determine if it needs to compare the Epoch times as well. + */ + bool operator!= (const ssfTime &rhs) const + {return (m_StoredTime != rhs.GetSeconds());}; + + /*! \brief output the time in seconds format + */ + friend std::ostream & operator << (std::ostream& s, ssfTime& t); +private: + ssfSeconds m_StoredTime; /*!< Internally stored time (seconds) */ + ssfSeconds m_EpochTime; /*!< Internatlly stored Epoch time (seconds) */ + +}; + + /*! \brief time used as epoch for measuring Greenwich sidereal time. + * + * + */ + static const ssfTime c_GreenwichSiderealEpochTime = ssfTime(1970,1,1,0,0,0); + /*! actual Greenwich sidereal time at the specified epoch, m_GreenwichSiderealEpochTime. */ + static const Angle c_GreenwichSiderealTimeAtEpoch = 1.74933340; + +/*! \brief Returns the current time in seconds since Midnight GMT, January 1st, 1970. + * \ingroup TimeUtils + * \relates Time + * @return number of seconds since Midnight UTC, January 1st, 1970 + */ +inline ssfSeconds Now() + {timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec + tv.tv_usec/1000000.);} + // {return time((time_t *)0);}; + + +/*! \brief Initializes the tick/tock counter +* \ingroup TimeUtils +* \relates Time +* +* Used for calculating the time during operations. First tick() is called, then +* when the operation has been completed tock() is called which returns the time (in seconds) +* since tick() was called. +* \sa tock() +\code +tick(); +for (int ii = 0; ii < 10; ++ii) { + ii += ii*ii; +} +cout << tock(); +\endcode +* the sample code would output the time it took to calculate \f$\sum{ii^2}\f$ to the console. +*/ +static ssfTime tickTime(-1); /*< global variable used to store the initial tick() time */ +static ssfTime tockTime(-1); /*< global variable used to store the ending tock() time */ + +inline void tick() +{ + tickTime.Set(Now()); + return; +} +/*! \brief Stops the tick/tock counter and returns the time (in seconds) since tick() was called. +* \ingroup TimeUtils +* \relates Time +* \sa tick() +*/ +inline ssfSeconds tock() +{ + if(tickTime.GetSeconds() > -1) + { + tockTime.Set(Now()); + return tockTime-tickTime; + } + else + return -1; +} + +/*! \brief Converts the day of the year (1-365) (given a year) to the Month and Day of they year +* \ingroup TimeUtils +* \relates Time +*/ +void DayofYear2YMD(int _dayOfYear, int _year, int &_month, int &_day); + +} // close namespace O_SESSAME + +#endif + +// Do not change the comments below - they will be added automatically by CVS +/***************************************************************************** +* $Log: Time.h,v $ +* Revision 1.15 2003/10/18 21:54:44 rsharo +* Fixed CF-LF problem and added missing comment. +* +* Revision 1.14 2003/10/18 21:37:29 rsharo +* Removed "../utils" from all qmake project paths. Prepended "utils +* /" to all #include directives for utils. Removed ".h" extensions from STL header +* s and referenced STL components from "std::" namespace. Overall, changed to be +* more portable. +* +* Revision 1.13 2003/06/11 14:22:34 nilspace +* Added comments to GetDateTime() and GetEpochDateTime() +* +* Revision 1.12 2003/06/10 01:11:46 nilspace +* Fixed Time to build correctly (changed Greenwich epoch time to object instead of pointer) +* +* Revision 1.11 2003/06/09 19:41:30 nilspace +* Added SetEpoch(year,month,day,hour,minute,second) +* +* Revision 1.10 2003/06/06 00:34:47 nilspace +* ? +* +* Revision 1.9 2003/05/21 03:57:52 nilspace +* Added GetEpochJulianDate and comments to JulianDate conversion function. +* +* Revision 1.8 2003/05/19 21:19:49 nilspace +* Made calls to overloaded Set() and SetEpoch() functions recursive calls to Set(ssfSeconds) and SetEpoch(ssfSeconds) +* +* Revision 1.7 2003/05/19 19:21:37 nilspace +* Added #include +* +* Revision 1.6 2003/05/16 14:01:24 nilspace +* Called gettimeofday(timeval*) to have Now(), and tick/tock return seconds with subsecond decimal parts. +* +* Revision 1.5 2003/05/09 23:44:29 nilspace +* Added operator!=() +* +* Revision 1.4 2003/04/30 16:32:48 nilspace +* Added operator== to ssfTime +* +* Revision 1.3 2003/04/27 22:04:34 nilspace +* Created the namespace O_SESSAME. +* +* Revision 1.2 2003/04/25 13:45:56 nilspace +* const'd Get() functions. +* +* Revision 1.1 2003/04/23 14:14:45 nilspace +* New simulation time. +* +* +******************************************************************************/ diff --git a/src/utils/TimeCompat.cpp b/src/utils/TimeCompat.cpp new file mode 100644 index 0000000..4dc50f9 --- /dev/null +++ b/src/utils/TimeCompat.cpp @@ -0,0 +1,72 @@ +#include + +/* Converts struct tm to time_t, assuming the data in tm is UTC rather + than local timezone. + + mktime is similar but assumes struct tm, also known as the + "broken-down" form of time, is in local time zone. mktime_from_utc + uses mktime to make the conversion understanding that an offset + will be introduced by the local time assumption. + + mktime_from_utc then measures the introduced offset by applying + gmtime to the initial result and applying mktime to the resulting + "broken-down" form. The difference between the two mktime results + is the measured offset which is then subtracted from the initial + mktime result to yield a calendar time which is the value returned. + + tm_isdst in struct tm is set to 0 to force mktime to introduce a + consistent offset (the non DST offset) since tm and tm+o might be + on opposite sides of a DST change. + + Some implementations of mktime return -1 for the nonexistent + localtime hour at the beginning of DST. In this event, use + mktime(tm - 1hr) + 3600. + + Schematically + mktime(tm) --> t+o + gmtime(t+o) --> tm+o + mktime(tm+o) --> t+2o + t+o - (t+2o - t+o) = t + + Note that glibc contains a function of the same purpose named + `timegm' (reverse of gmtime). But obviously, it is not universally + available, and unfortunately it is not straightforwardly + extractable for use here. Perhaps configure should detect timegm + and use it where available. + + Contributed by Roger Beeman , with the help of + Mark Baushke and the rest of the Gurus at CISCO. + Further improved by Roger with assistance from Edward J. Sabol + based on input by Jamie Zawinski. */ + +time_t +mktime_from_utc (struct tm *t) +{ + time_t tl, tb; + struct tm *tg; + + tl = mktime (t); + if (tl == -1) + { + t->tm_hour--; + tl = mktime (t); + if (tl == -1) + return -1; /* can't deal with output from strptime */ + tl += 3600; + } + tg = gmtime (&tl); + tg->tm_isdst = 0; + tb = mktime (tg); + if (tb == -1) + { + tg->tm_hour--; + tb = mktime (tg); + if (tb == -1) + return -1; /* can't deal with output from gmtime */ + tb += 3600; + } + return (tl - (tb - tl)); +} + + + diff --git a/src/utils/math.pro b/src/utils/math.pro new file mode 100644 index 0000000..1b51b32 --- /dev/null +++ b/src/utils/math.pro @@ -0,0 +1,32 @@ +# +# $Id: math.pro,v 1.4 2003/10/18 21:37:29 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = Integrator.h RungeKuttaIntegrator.h \ + RungeKuttaFehlbergIntegrator.h\ + Interpolator.h LinearInterpolator.h \ + Functor.h +SOURCES = RungeKuttaIntegrator.cpp RungeKuttaFehlbergIntegrator.cpp \ + LinearInterpolator.cpp \ + TimeCompat.cpp +TARGET = osessame_math +VERSION = 1.0 + + +DESTDIR = ../../lib/ +INCLUDEPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment .. +CONFIG = console staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment ../utils diff --git a/src/utils/utils.pro b/src/utils/utils.pro new file mode 100644 index 0000000..2cb0132 --- /dev/null +++ b/src/utils/utils.pro @@ -0,0 +1,27 @@ +# +# $Id: utils.pro,v 1.4 2003/10/18 21:37:29 rsharo Exp $ +# +# Copyright (C) 2002-2003 by Andrew J. Turner. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation under the terms of the GNU General Public License is hereby +# granted. No representations are made about the suitability of this software +# for any purpose. It is provided "as is" without express or implied warranty. +# See the GNU General Public License for more details. + +HEADERS = Time.h Plot.h +SOURCES = Time.cpp Plot.cpp TimeCompat.cpp +TARGET = osessame_utils +VERSION = 1.0 + + +DESTDIR = ../../lib/ +INCLUDEPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment .. +CONFIG = console staticlib warn_on debug +TEMPLATE = lib +OBJECTS_DIR = ../../objects +DEPENDPATH = ../matrix/ ../rotation ../attitude \ + ../orbit ../datahandling ../dynamics \ + ../environment ../utils