source: trunk/optimizer/src/rp_optimizer.c @ 898

Last change on this file since 898 was 898, checked in by mmc, 16 years ago

Optimization part is getting better. Fleshed out the plug-in for
PGApack, and integrated a first cut that includes the data handling.

File size: 8.1 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  rp_optimizer
4 *
5 *  This is the C language API for the optimization package in
6 *  Rappture.  It lets you set up an optimization of some fitness
7 *  function with respect to a set of inputs.
8 *
9 * ======================================================================
10 *  AUTHOR:  Michael McLennan, Purdue University
11 *  Copyright (c) 2008  Purdue Research Foundation
12 *
13 *  See the file "license.terms" for information on usage and
14 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15 * ======================================================================
16 */
17#include <math.h>
18#include <stdlib.h>
19#include <string.h>
20#include "rp_optimizer.h"
21
22static void RpOptimCleanupParam _ANSI_ARGS_((RpOptimParam *paramPtr));
23
24/*
25 * ----------------------------------------------------------------------
26 * RpOptimCreate()
27 *
28 * Used to create the context for an optimization.  Creates an empty
29 * context and returns a pointer to it.  The context can be updated
30 * by calling functions like RpOptimAddParamNumber to define various
31 * input parameters.
32 * ----------------------------------------------------------------------
33 */
34RpOptimEnv*
35RpOptimCreate(pluginData, cleanupProc)
36    ClientData pluginData;        /* special data created for this env */
37    RpOptimCleanup *cleanupProc;  /* routine to clean up pluginData */
38{
39    RpOptimEnv *envPtr;
40    envPtr = (RpOptimEnv*)malloc(sizeof(RpOptimEnv));
41    envPtr->pluginData  = pluginData;
42    envPtr->cleanupProc = cleanupProc;
43    envPtr->toolData    = NULL;
44
45    envPtr->numParams = 0;
46    envPtr->maxParams = 5;
47    envPtr->paramList = (RpOptimParam**)malloc(
48        (size_t)(envPtr->maxParams*sizeof(RpOptimParam*))
49    );
50
51    return envPtr;
52}
53
54/*
55 * ----------------------------------------------------------------------
56 * RpOptimAddParam()
57 *
58 * Used internally to add a new parameter into the given optimization
59 * context.  The internal list of parameters is resized, if necessary,
60 * to accommodate the new parameter.
61 * ----------------------------------------------------------------------
62 */
63void
64RpOptimAddParam(envPtr, paramPtr)
65    RpOptimEnv *envPtr;      /* context for this optimization */
66    RpOptimParam *paramPtr;  /* parameter being added */
67{
68    RpOptimParam **newParamList;
69
70    /*
71     * Add the new parameter at the end of the list.
72     */
73    envPtr->paramList[envPtr->numParams++] = paramPtr;
74
75    /*
76     * Out of space?  Then double the space available for params.
77     */
78    if (envPtr->numParams >= envPtr->maxParams) {
79        envPtr->maxParams *= 2;
80        newParamList = (RpOptimParam**)malloc(
81            (size_t)(envPtr->maxParams*sizeof(RpOptimParam*))
82        );
83        memcpy(newParamList, envPtr->paramList,
84            (size_t)(envPtr->numParams*sizeof(RpOptimParam*)));
85        free(envPtr->paramList);
86        envPtr->paramList = newParamList;
87    }
88}
89
90/*
91 * ----------------------------------------------------------------------
92 * RpOptimAddParamNumber()
93 *
94 * Used to add a number parameter as an input to an optimization.
95 * Each number has a name and a double precision value that can be
96 * constrained between min/max values.  Adds this number to the end
97 * of the parameter list in the given optimization context.
98 * ----------------------------------------------------------------------
99 */
100RpOptimParam*
101RpOptimAddParamNumber(envPtr, name)
102    RpOptimEnv *envPtr;   /* context for this optimization */
103    char *name;           /* name of this parameter */
104{
105    RpOptimParamNumber *numPtr;
106    numPtr = (RpOptimParamNumber*)malloc(sizeof(RpOptimParamNumber));
107    numPtr->base.name = strdup(name);
108    numPtr->base.type = RP_OPTIMPARAM_NUMBER;
109    numPtr->base.value.dval = 0.0;
110    numPtr->min = -DBL_MAX;
111    numPtr->max = DBL_MAX;
112
113    RpOptimAddParam(envPtr, (RpOptimParam*)numPtr);
114
115    return (RpOptimParam*)numPtr;
116}
117
118/*
119 * ----------------------------------------------------------------------
120 * RpOptimAddParamString()
121 *
122 * Used to add a string parameter as an input to an optimization.
123 * Each string has a name and a list of allowed values terminated
124 * by a NULL.  Adds this string to the end of the parameter list
125 * in the given optimization context.
126 * ----------------------------------------------------------------------
127 */
128RpOptimParam*
129RpOptimAddParamString(envPtr, name)
130    RpOptimEnv *envPtr;   /* context for this optimization */
131    char *name;           /* name of this parameter */
132{
133    RpOptimParamString *strPtr;
134    strPtr = (RpOptimParamString*)malloc(sizeof(RpOptimParamString));
135    strPtr->base.name = strdup(name);
136    strPtr->base.type = RP_OPTIMPARAM_STRING;
137    strPtr->base.value.sval.num = -1;
138    strPtr->base.value.sval.str = NULL;
139    strPtr->values = NULL;
140    strPtr->numValues = 0;
141
142    RpOptimAddParam(envPtr, (RpOptimParam*)strPtr);
143
144    return (RpOptimParam*)strPtr;
145}
146
147/*
148 * ----------------------------------------------------------------------
149 * RpOptimFindParam()
150 *
151 * Used to look for an existing parameter with the specified name.
152 * Returns a pointer to the parameter, or NULL if not found.
153 * ----------------------------------------------------------------------
154 */
155RpOptimParam*
156RpOptimFindParam(envPtr, name)
157    RpOptimEnv *envPtr;   /* context for this optimization */
158    char *name;           /* name of this parameter */
159{
160    int n;
161    for (n=0; envPtr->numParams; n++) {
162        if (strcmp(name, envPtr->paramList[n]->name) == 0) {
163            return envPtr->paramList[n];
164        }
165    }
166    return NULL;
167}
168
169/*
170 * ----------------------------------------------------------------------
171 * RpOptimDeleteParam()
172 *
173 * Used to delete a parameter from the environment.  This is especially
174 * useful when an error is found while configuring the parameter, just
175 * after it was created.  If the name is not recognized, this function
176 * does nothing.
177 * ----------------------------------------------------------------------
178 */
179void
180RpOptimDeleteParam(envPtr, name)
181    RpOptimEnv *envPtr;   /* context for this optimization */
182    char *name;           /* name of this parameter */
183{
184    int n, j;
185    for (n=0; envPtr->numParams; n++) {
186        if (strcmp(name, envPtr->paramList[n]->name) == 0) {
187            RpOptimCleanupParam(envPtr->paramList[n]);
188            for (j=n+1; j < envPtr->numParams; j++) {
189                envPtr->paramList[j-1] = envPtr->paramList[j];
190            }
191            envPtr->numParams--;
192            break;
193        }
194    }
195}
196
197/*
198 * ----------------------------------------------------------------------
199 * RpOptimDelete()
200 *
201 * Used to delete the context for an optimization once it is finished
202 * or no longer needed.  Frees up the memory needed to store the
203 * context and all input parameters.  After this call, the context
204 * should not be used again.
205 * ----------------------------------------------------------------------
206 */
207void
208RpOptimDelete(envPtr)
209    RpOptimEnv *envPtr;   /* context for this optimization */
210{
211    int n;
212
213    for (n=0; n < envPtr->numParams; n++) {
214        RpOptimCleanupParam(envPtr->paramList[n]);
215    }
216    if (envPtr->cleanupProc) {
217        (*envPtr->cleanupProc)(envPtr->pluginData);
218    }
219    free(envPtr->paramList);
220    free(envPtr);
221}
222
223/*
224 * ----------------------------------------------------------------------
225 * RpOptimCleanupParam()
226 *
227 * Used internally to free up the data associated with an optimization
228 * parameter.  Looks at the parameter type and frees up the appropriate
229 * data.
230 * ----------------------------------------------------------------------
231 */
232static void
233RpOptimCleanupParam(paramPtr)
234    RpOptimParam *paramPtr;  /* data to be freed */
235{
236    int n;
237    RpOptimParamNumber *numPtr;
238    RpOptimParamString *strPtr;
239
240    free(paramPtr->name);
241    switch (paramPtr->type) {
242        case RP_OPTIMPARAM_NUMBER:
243            numPtr = (RpOptimParamNumber*)paramPtr;
244            /* nothing special to free here */
245            break;
246        case RP_OPTIMPARAM_STRING:
247            strPtr = (RpOptimParamString*)paramPtr;
248            if (strPtr->values) {
249                for (n=0; strPtr->values[n]; n++) {
250                    free(strPtr->values[n]);
251                }
252            }
253            break;
254    }
255    free(paramPtr);
256}
Note: See TracBrowser for help on using the repository browser.