1 /*
2 
3 -Procedure vtmvg_c  ( Vector transpose times matrix times vector )
4 
5 -Abstract
6 
7     Multiply the transpose of a n-dimensional column vector,
8     a nxm matrix, and a m-dimensional column vector.
9 
10 -Disclaimer
11 
12    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
13    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
14    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
15    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
16    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
17    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
18    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
19    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
20    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
21    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
22 
23    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
24    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
25    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
26    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
27    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
28    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
29 
30    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
31    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
32    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
33    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
34 
35 -Required_Reading
36 
37     None.
38 
39 -Keywords
40 
41     MATRIX
42     VECTOR
43 
44 */
45 
46    #include "SpiceUsr.h"
47    #undef vtmvg_c
48 
vtmvg_c(const void * v1,const void * matrix,const void * v2,SpiceInt nrow,SpiceInt ncol)49    SpiceDouble vtmvg_c ( const void          * v1,
50                          const void          * matrix,
51                          const void          * v2,
52                          SpiceInt              nrow,
53                          SpiceInt              ncol    )
54 
55 /*
56 
57 -Brief_I/O
58 
59     VARIABLE  I/O  DESCRIPTION
60     --------  ---  --------------------------------------------------
61      v1        I   n-dimensional double precision column vector.
62      matrix    I   nxm double precision matrix.
63      v2        I   m-dimensional double porecision column vector.
64      nrow      I   Number of rows in matrix (number of rows in v1.)
65      ncol      I   Number of columns in matrix (number of rows in
66                    v2.)
67 
68      The function returns the result of (v1**t * matrix * v2 ).
69 
70 -Detailed_Input
71 
72     v1         is an n-dimensional double precision vector.
73 
74     matrix     is an n x m double precision matrix.
75 
76     v2         is an m-dimensional double precision vector.
77 
78     nrow       is the number of rows in matrix.  this is also
79                equivalent to the number of rows in the vector v1.
80 
81     ncol       is the number of columns in matrix. this is also
82                equivalent to the number of rows in the vector v2.
83 
84 -Detailed_Output
85 
86     The function returns the double precision value of the equation
87     (v1**t * matrix * v2 ).
88 
89     Notice that vtmvg_c is actually the dot product of the vector
90     resulting from multiplying the transpose of V1 and MATRIX and the
91     vector V2.
92 
93 -Parameters
94 
95     None.
96 
97 -Particulars
98 
99     This routine implements the following vector/matrix/vector
100     multiplication:
101 
102                            T
103        vtmvg_c = [   V1   ] |          |  |  |
104                             |  MATRIX  |  |V2|
105                             |          |  |  |
106 
107     by calculating over all values of the indices k and l from 1 to
108     nrow and 1 to ncol, respectively, the expression
109 
110        vtmvg_c = Summation of ( v1(k)*matrix(k,l)*v2(l) ) .
111 
112     v1 is a column vector which becomes a row vector when transposed.
113     v2 is a column vector.
114 
115     No check performed to determine whether floating point
116     overflow has occurred.
117 
118 -Examples
119 
120     If  v1 = | 1.0 |  matrix = | 2.0  0.0 |  v2 = | 1.0 |
121              |     |           |          |       |     |
122              | 2.0 |           | 1.0  2.0 |       | 2.0 |
123              |     |           |          |
124              | 3.0 |           | 1.0  1.0 |
125 
126     nrow = 3
127     ncol = 2
128 
129     Then the value of the function is  21.0.
130 
131 -Restrictions
132 
133     Since no error detection or recovery is implemented, the
134     programmer is required to insure that the inputs to this routine
135     are both valid and within the proper range.
136 
137 -Exceptions
138 
139    Error free.
140 
141 -Files
142 
143     None.
144 
145 -Author_and_Institution
146 
147     W.M. Owen       (JPL)
148     E.D. Wright     (JPL)
149 
150 -Literature_References
151 
152     None.
153 
154 -Version
155 
156    -CSPICE Version 1.0.0, 1-JUL-1999
157 
158 -Index_Entries
159 
160    n-dimensional vector_transpose times matrix times vector
161 
162 -&
163 */
164 
165 { /* Begin vtmvg_c */
166 
167 
168    /*
169    Local macros
170 
171    We'd like to be able to refer to the elements of the input and output
172    matrices using normal subscripts, for example, m1[2][3].  Since the
173    compiler doesn't know how to compute index offsets for the array
174    arguments, which have user-adjustable size, we must compute the
175    offsets ourselves.  To make syntax a little easier to read (we hope),
176    we'll use macros to do the computations.
177 
178    The macro INDEX(width, i,j) computes the index offset from the array
179    base of the element at position [i][j] in a 2-dimensional matrix
180    having the number of columns indicated by width.  For example, if
181    the input matrix m1 has 2 rows and 3 columns, the element at position
182    [0][1] would be indicated by
183 
184       m1[ INDEX(3,0,1) ]
185 
186    */
187 
188    #define INDEX( width, row, col )     ( (row)*(width) + (col) )
189 
190 
191    /*
192    Local variables
193    */
194    ConstSpiceDouble      * loc_v1;
195    ConstSpiceDouble      * loc_m1;
196    ConstSpiceDouble      * loc_v2;
197 
198 
199    SpiceInt                k;
200    SpiceInt                l;
201    SpiceDouble             val = 0.;
202 
203 
204    loc_v1 = ( ConstSpiceDouble * ) v1;
205    loc_v2 = ( ConstSpiceDouble * ) v2;
206    loc_m1 = ( ConstSpiceDouble * ) matrix;
207 
208 
209    for ( k = 0; k < nrow; k++ )
210       {
211       for ( l = 0; l < ncol; l++ )
212          {
213          val += loc_v1[k] * loc_m1[ INDEX(ncol,k,l) ] * loc_v2[l];
214          }
215       }
216 
217    return val;
218 
219 } /* End vtmvg_c */
220