Initial working implementation of new dependency tracking.
[openmx:openmx.git] / src / omxState.h
1 /*
2  *  Copyright 2007-2012 The OpenMx Project
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *   Unless required by applicable law or agreed to in writing, software
11  *   distributed under the License is distributed on an "AS IS" BASIS,
12  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16
17 /***********************************************************
18 *
19 *  omxState.h
20 *
21 *  Created: Timothy R. Brick    Date: 2009-05-23
22 *
23 *       Contains header information for the omxState structure
24 *   omxStates keep the current optimization state.
25 *
26 **********************************************************/
27
28 #ifndef _OMXSTATE_H_
29 #define _OMXSTATE_H_
30
31 #include "R.h"
32 #include <Rinternals.h>
33 #include <Rdefines.h>
34 #include <R_ext/Rdynload.h>
35 #include <R_ext/BLAS.h>
36 #include <R_ext/Lapack.h>
37 #include <sys/types.h>
38
39 #ifdef WIN32
40
41 #include <winsock.h>
42
43 #else
44
45 #include <sys/socket.h>
46 #include <netinet/in.h>
47 #include <netdb.h>
48
49 #endif
50
51 #include <time.h>
52 #include <unistd.h>
53 #include "omxDefines.h"
54
55 /* Forward declarations for later includes */
56 typedef struct omxState omxState;
57 typedef struct omxFreeVar omxFreeVar;
58 typedef struct omxConstraint omxConstraint;
59 typedef struct omxCheckpoint omxCheckpoint;
60 typedef enum omxCheckpointType omxCheckpointType;
61 typedef struct omxOptimizerState omxOptimizerState;
62 typedef struct omxConfidenceInterval omxConfidenceInterval;
63
64 #include "omxMatrix.h"
65 #include "omxAlgebra.h"
66 #include "omxObjective.h"
67 #include "omxData.h"
68 //#include "omxOptimizer.h"                                                                                     // omxOptimizer objects coming soon
69
70 /* Structure definitions for object evaluation */  // Might be cleaner to give these their own files.
71 struct omxFreeVar {                     // Free Variables
72         double lbound, ubound;  // Bounds
73         int numLocations;
74         int* matrices;                  // Matrix numbers.
75         int *row, *col;                 // Locations for copying.
76         int numDeps;            // number of algebra/matrix dependencies
77         int *deps;              // indices of algebra/matrix dependencies
78         const char* name;
79 };
80
81 struct omxConstraint {          // Free Variable Constraints
82         int size;
83         int opCode;
84         double* lbound;
85         double* ubound;
86         omxMatrix* result;
87 };
88
89 struct omxOptimizerState {                      // For hessian or confidence interval computation
90         int currentParameter;                   // Which parameter is being examined?
91         double offset;                                  // Current offset of optimization
92         short int alpha;                                // Parameter multiplier
93         // Objective should be:  (3.84 - (-2LL))^2 + alpha * parameter
94         // Alpha should generally be +1 to minimize parameter -1 to maximize
95 };
96
97 enum omxCheckpointType {
98         OMX_FILE_CHECKPOINT = 0,
99         OMX_SOCKET_CHECKPOINT = 1,
100         OMX_CONNECTION_CHECKPOINT = 2
101 };
102
103 struct omxCheckpoint {
104         omxCheckpointType type;
105         time_t time;
106         int numIterations;
107         unsigned long int lastCheckpoint;       // FIXME: Cannot update at sub-second times.
108         FILE* file;                                             // TODO: Maybe make the connection piece a union instead.
109         int socket;
110         SEXP connection;
111         unsigned short int saveHessian;
112 };
113
114 struct omxConfidenceInterval {          // For Confidence interval request
115         omxMatrix* matrix;                              // The matrix
116         int row, col;                                   // Location of element to calculate
117         double ubound;                                  // Objective-space upper boundary
118         double lbound;                                  // Objective-space lower boundary
119         double max;                                             // Value at upper bound
120         double min;                                             // Value at lower bound
121         int lCode;                                              // Optimizer code at lower bound
122         int uCode;                                              // Optimizer code at upper bound
123         unsigned short calcLower;               // Are we currently calculating lbound?
124 };
125
126 #define MAX_STRING_LEN 250
127
128 struct omxState {                                                                                                       // The Current State of Optimization
129
130 /* Model and Optimizer Pointers */
131
132 //      omxOptimizer* optimizer;                                                                                // Current Optimizer
133         int numMats, numAlgs, numData, numChildren;                                             // Number of matrices, algebras, and data elements
134         omxMatrix** matrixList;                                                                                 // Model Matrices
135         omxMatrix** algebraList;                                                                                // Model Algebras
136         omxData** dataList;                                                                                             // Data Objects
137         omxState** childList;                                                                                   // List of child states
138         omxState* parentState;                                                                                  // Parent State
139
140                                                                     // TODO: Need a way to deal with unregistered matrices that have free vars
141         omxMatrix* objectiveMatrix;                                                                             // Objective Algebra
142
143         /* May want to farm these out to the omxObjective object. */
144         int numConstraints;
145         omxConstraint* conList;                                                                                 // List of constraints
146         int numIntervals;
147         int currentInterval;                                                                                    // The interval currently being calculated
148         omxConfidenceInterval* intervalList;                                                    // List of confidence intervals requested
149
150         int numFreeParams;
151         omxFreeVar* freeVarList;                                                                                // List of Free Variables and where they go.
152
153         /* Saved Optimum State */ // TODO: Rename saved optimum state
154         double* optimalValues;                                                                                  // Values of the free parameters at the optimum value
155         double optimum;                                                                                                 // Objective value at last saved optimum
156         double* hessian;                                                                                                // Current hessian storage
157         int optimumStatus;                                                                                              // Optimizer status of last saved optimum (0=converged, 1=green, -1=error, >1=red)
158         char optimumMsg[250];                                                                                   // Status message of last saved optimum
159         omxOptimizerState* optimizerState;                                                              // Current optimum parameters for limit computation
160
161 /* Current Optimization State (optimizer-specific) */
162 //      void* optimizerInfo;                                                                                    // Optimizer specific storage
163
164 /* Data members for use by Objective Function and Algebra Calculations */
165         long int computeCount;                                                                                  // How many times have things been evaluated so far?
166         long int currentRow;                                                                                    // If we're calculating row-by-row, what row are we on?
167
168         /* For Checkpointing */
169         int majorIteration;                                                                                             // Major iteration number
170         int minorIteration;                                                                                             // Minor iteration within major iteration
171         time_t startTime;                                                                                               // Time of first computation
172         time_t endTime;                                                                                                 // 'Cause we might as well report it
173         omxCheckpoint* checkpointList;                                                                  // List of checkpoints
174         char *chkptText1, *chkptText2;                                                                  // Placeholders for checkpointing text
175         int numCheckpoints;                                                                                             // Number of checkpoints
176
177         int statusCode;                                                                                                 // Status code, if appropriate
178         char statusMsg[250];                                                                                    // Status/Error message to report
179         double saturatedModel;                                                                                  // Saturated model likelihood, where applicable
180         int analyticGradients;
181 };
182
183 /* Initialize and Destroy */
184         void omxInitState(omxState* state, omxState *parentState, int numChildren); // Constructor
185         void omxFillState(omxState* state, /*omxOptimizer *oo,*/ omxMatrix** matrixList, omxMatrix** algebraList, omxData** dataList, omxMatrix* objective);
186         void omxFreeState(omxState *state);                                                                     // Destructor
187         void omxSaveState(omxState *os, double* freeVals, double minimum);      // Saves the current optimization values //TODO: Rename omxSaveState.
188         void omxUpdateState(omxState* tgt, omxState* src, int copyStatus);      // Updates the tgt state with the contents of src state
189         void omxPartialUpdateState(omxState* tgt, omxState* src, omxMatrix *tgtMatrix,
190                                omxMatrix *srcMatrix, int copyStatus);    // Updates the tgt state with the contents of src state ONLY for the specific matrix and its dependencies
191         void omxDuplicateState(omxState *tgt, omxState* src); 
192         int omxTotalThreadCount(omxState *state);
193                                                                         // Duplicates the current state object
194         omxState* omxGetState(omxState *os, int stateNum);                                      // Retrieve a child by number
195
196         void omxSetMajorIteration(omxState *state, int value);                          // Recursively set major iteration number
197         void omxSetMinorIteration(omxState *state, int value);                          // Recursively set minor iteration number
198
199         omxMatrix* omxLookupDuplicateElement(omxState* os, omxMatrix* element);
200     
201         void omxRaiseError(omxState *state, int errorCode, char* errorMsg);     // Raise an Error
202                                                                                                                                                 // TODO: Move RaiseError to omxOptimizer.
203
204 /* Advance a step */
205         void omxStateNextRow(omxState *state);                                                          // Advance Row
206         void omxStateNextEvaluation(omxState *state);                                           // Advance Evaluation count
207
208         void omxSaveCheckpoint(omxState* os, double* x, double* f, int force);  // Save out checkpoints
209
210 #endif /* _OMXSTATE_H_ */
211
212