1 // Copyright (c) 2015-2016, Massachusetts Institute of Technology
2 // Copyright (c) 2016-2017 Sandia Corporation
3 // Copyright (c) 2017 NTESS, LLC.
4 
5 // This file is part of the Compressed Continuous Computation (C3) Library
6 // Author: Alex A. Gorodetsky
7 // Contact: alex@alexgorodetsky.com
8 
9 // All rights reserved.
10 
11 // Redistribution and use in source and binary forms, with or without modification,
12 // are permitted provided that the following conditions are met:
13 
14 // 1. Redistributions of source code must retain the above copyright notice,
15 //    this list of conditions and the following disclaimer.
16 
17 // 2. Redistributions in binary form must reproduce the above copyright notice,
18 //    this list of conditions and the following disclaimer in the documentation
19 //    and/or other materials provided with the distribution.
20 
21 // 3. Neither the name of the copyright holder nor the names of its contributors
22 //    may be used to endorse or promote products derived from this software
23 //    without specific prior written permission.
24 
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 
36 //Code
37 
38 
39 
40 
41 
42 
43 /** \file fapprox.c
44  * Provides basic routines for approximating functions
45  */
46 
47 #include <stdlib.h>
48 #include <assert.h>
49 #include <stdio.h>
50 
51 #include "fapprox.h"
52 
53 /***********************************************************//**
54   Allocate one dimensional approximations
55 ***************************************************************/
56 struct OneApproxOpts *
one_approx_opts_alloc(enum function_class fc,void * aopts)57 one_approx_opts_alloc(enum function_class fc, void * aopts)
58 {
59 
60     struct OneApproxOpts * app = malloc(sizeof(struct OneApproxOpts));
61     if (app == NULL){
62         fprintf(stderr,"Cannot allocate OneApproxOpts\n");
63         exit(1);
64     }
65     app->fc = fc;
66     app->aopts = aopts;
67     return app;
68 }
69 
70 /***********************************************************//**
71   Allocate one dimensional approximations
72 ***************************************************************/
73 struct OneApproxOpts *
one_approx_opts_alloc_ref(enum function_class fc,void ** aopts)74 one_approx_opts_alloc_ref(enum function_class fc, void ** aopts)
75 {
76 
77     struct OneApproxOpts * app = malloc(sizeof(struct OneApproxOpts));
78     if (app == NULL){
79         fprintf(stderr,"Cannot allocate OneApproxOpts\n");
80         exit(1);
81     }
82     app->fc = fc;
83     app->aopts = *aopts;
84     return app;
85 }
86 
87 /***********************************************************//**
88   Free one dimensional approximations
89 ***************************************************************/
one_approx_opts_free(struct OneApproxOpts * oa)90 void one_approx_opts_free(struct OneApproxOpts * oa)
91 {
92     if (oa != NULL){
93         free(oa); oa = NULL;
94     }
95 }
96 
97 /***********************************************************//**
98   Free one dimensional approximations (deep)
99 ***************************************************************/
one_approx_opts_free_deep(struct OneApproxOpts ** oa)100 void one_approx_opts_free_deep(struct OneApproxOpts ** oa)
101 {
102     if (*oa != NULL){
103         if ((*oa)->fc == PIECEWISE){
104             struct PwPolyOpts * opts = (*oa)->aopts;
105             pw_poly_opts_free(opts);
106             (*oa)->aopts = NULL;
107         }
108         else if ((*oa)->fc == POLYNOMIAL){
109             struct OpeOpts * opts = (*oa)->aopts;
110             ope_opts_free_deep(&opts); (*oa)->aopts = NULL;
111             ope_opts_free(opts);
112             (*oa)->aopts = NULL;
113         }
114         else if ((*oa)->fc == LINELM){
115             struct LinElemExpAopts * opts = (*oa)->aopts;
116             lin_elem_exp_aopts_free(opts);
117             (*oa)->aopts = NULL;
118         }
119         else if ((*oa)->fc == CONSTELM){
120             struct ConstElemExpAopts * opts = (*oa)->aopts;
121             const_elem_exp_aopts_free(opts);
122             (*oa)->aopts = NULL;
123         }
124         else if ((*oa)->fc == KERNEL){
125             struct KernelApproxOpts * opts = (*oa)->aopts;
126             kernel_approx_opts_free(opts);
127             (*oa)->aopts = NULL;
128         }
129         else{
130             fprintf(stderr,"Cannot free one_approx options of type %d\n",
131                     (*oa)->fc);
132         }
133         free(*oa); *oa = NULL;
134     }
135 }
136 
137 
138 /***********************************************************//**
139   Get the number of parametrs in the approximation optins
140 ***************************************************************/
one_approx_opts_get_nparams(const struct OneApproxOpts * oa)141 size_t one_approx_opts_get_nparams(const struct OneApproxOpts * oa)
142 {
143     assert (oa != NULL);
144     assert (oa->aopts != NULL);
145     size_t nparams = 0;
146     if (oa->fc == POLYNOMIAL){
147         nparams = ope_opts_get_nparams(oa->aopts);
148     }
149     else if (oa->fc == PIECEWISE){
150         nparams = pw_poly_opts_get_nparams(oa->aopts);
151     }
152     else if (oa->fc == LINELM){
153         nparams = lin_elem_exp_aopts_get_nparams(oa->aopts);
154     }
155     else if (oa->fc == CONSTELM){
156         nparams = const_elem_exp_aopts_get_nparams(oa->aopts);
157     }
158     else if (oa->fc == KERNEL){
159         nparams = kernel_approx_opts_get_nparams(oa->aopts);
160     }
161     else{
162         fprintf(stderr,"Cannot get number of parameters for one_approx options of type %d\n",
163                 oa->fc);
164     }
165     return nparams;
166 }
167 
168 /***********************************************************//**
169   Get the lower bounds
170 ***************************************************************/
one_approx_opts_get_lb(const struct OneApproxOpts * oa)171 double one_approx_opts_get_lb(const struct OneApproxOpts * oa)
172 {
173     assert (oa != NULL);
174     assert (oa->aopts != NULL);
175     double lb = 0.0;
176     if (oa->fc == POLYNOMIAL){
177         lb = ope_opts_get_lb(oa->aopts);
178     }
179     else if (oa->fc == PIECEWISE){
180         lb = pw_poly_opts_get_lb(oa->aopts);
181     }
182     else if (oa->fc == LINELM){
183         lb = lin_elem_exp_aopts_get_lb(oa->aopts);
184     }
185     else if (oa->fc == CONSTELM){
186         lb = const_elem_exp_aopts_get_lb(oa->aopts);
187     }
188     else if (oa->fc == KERNEL){
189         lb = kernel_approx_opts_get_lb(oa->aopts);
190     }
191     else{
192         fprintf(stderr,"Cannot get lower_bound for one_approx options of type %d\n",
193                 oa->fc);
194     }
195     return lb;
196 }
197 
198 /***********************************************************//**
199   Get the upper bounds
200 ***************************************************************/
one_approx_opts_get_ub(const struct OneApproxOpts * oa)201 double one_approx_opts_get_ub(const struct OneApproxOpts * oa)
202 {
203     assert (oa != NULL);
204     assert (oa->aopts != NULL);
205     double ub = 0.0;
206     if (oa->fc == POLYNOMIAL){
207         ub = ope_opts_get_ub(oa->aopts);
208     }
209     else if (oa->fc == PIECEWISE){
210         ub = pw_poly_opts_get_ub(oa->aopts);
211     }
212     else if (oa->fc == LINELM){
213         ub = lin_elem_exp_aopts_get_ub(oa->aopts);
214     }
215     else if (oa->fc == CONSTELM){
216         ub = const_elem_exp_aopts_get_ub(oa->aopts);
217     }
218     else if (oa->fc == KERNEL){
219         ub = kernel_approx_opts_get_ub(oa->aopts);
220     }
221     else{
222         fprintf(stderr,"Cannot get upper bound for one_approx options of type %d\n",
223                 oa->fc);
224     }
225     return ub;
226 }
227 
228 
229 /***********************************************************//**
230   Set the number of parametrs in the approximation optins
231 ***************************************************************/
one_approx_opts_set_nparams(struct OneApproxOpts * oa,size_t num)232 void one_approx_opts_set_nparams(struct OneApproxOpts * oa, size_t num)
233 {
234     assert (oa != NULL);
235     assert (oa->aopts != NULL);
236     if (oa->fc == POLYNOMIAL){
237         ope_opts_set_nparams(oa->aopts,num);
238     }
239     else if (oa->fc == PIECEWISE){
240         pw_poly_opts_set_nparams(oa->aopts,num);
241     }
242     else if (oa->fc == LINELM){
243         lin_elem_exp_aopts_set_nparams(oa->aopts,num);
244     }
245     else if (oa->fc == CONSTELM){
246         const_elem_exp_aopts_set_nparams(oa->aopts,num);
247     }
248     else if (oa->fc == KERNEL){
249         kernel_approx_opts_set_nparams(oa->aopts,num);
250     }
251     else{
252         fprintf(stderr,"Cannot set number of parameters for one_approx options of type %d\n",
253                 oa->fc);
254     }
255 }
256 
257 /***********************************************************//**
258   Set the maximum number of parametrs in the approximation optins
259 ***************************************************************/
one_approx_opts_set_maxnum(struct OneApproxOpts * oa,size_t num)260 void one_approx_opts_set_maxnum(struct OneApproxOpts * oa, size_t num)
261 {
262     assert (oa != NULL);
263     assert (oa->aopts != NULL);
264     if (oa->fc == POLYNOMIAL){
265         ope_opts_set_maxnum(oa->aopts,num);
266     }
267     /* else if (oa->fc == PIECEWISE){ */
268     /*     pw_poly_opts_set_maxnum(oa->aopts,num); */
269     /* } */
270     /* else if (oa->fc == LINELM){ */
271     /*     lin_elem_exp_aopts_set_maxnum(oa->aopts,num); */
272     /* } */
273     /* else if (oa->fc == CONSTELM){ */
274     /*     const_elem_exp_aopts_set_maxnum(oa->aopts,num); */
275     /* }     */
276     /* else if (oa->fc == KERNEL){ */
277     /*     kernel_approx_opts_set_maxnum(oa->aopts,num); */
278     /* } */
279     else{
280         fprintf(stderr,"Cannot set maximum number of parameters for one_approx options of type %d\n",
281                 oa->fc);
282     }
283 }
284 
285 
286 /***********************************************************//**
287   Check whether the unknowns are linearly related to the function output.
288   Typically used for regression to extract particular structure
289 ***************************************************************/
one_approx_opts_linear_p(const struct OneApproxOpts * oa)290 int one_approx_opts_linear_p(const struct OneApproxOpts * oa)
291 {
292     assert (oa != NULL);
293     assert (oa->aopts != NULL);
294     int lin = 0;
295     if (oa->fc == POLYNOMIAL){
296         lin = 1;
297     }
298     else if (oa->fc == PIECEWISE){
299         assert (1 == 0);
300     }
301     else if (oa->fc == LINELM){
302         lin = 1;
303     }
304     else if (oa->fc == CONSTELM){
305         lin = 1;
306     }
307     else if (oa->fc == KERNEL){
308         lin = kernel_approx_opts_linear_p(oa->aopts);
309     }
310     else{
311         fprintf(stderr,"Cannot get number of parameters for one_approx options of type %d\n",
312                 oa->fc);
313     }
314     return lin;
315 }
316 
317 
318 
319 
320 //////////////////////////////////////////////////////
321 /** \struct MultiApproxOpts
322  * \brief Stores approximation options for multiple one dimensional functions
323  * \var MultiApproxOpts::dim
324  * Number of functions
325  * \var MultiApproxOpts::aopts
326  * function approximation options
327  */
328 struct MultiApproxOpts
329 {
330     size_t dim;
331     struct OneApproxOpts ** aopts;
332 };
333 
334 /***********************************************************//**
335   Allocate multi_approx_opts
336 
337   \param[in] dim - dimension
338 
339   \return approximation options
340 ***************************************************************/
multi_approx_opts_alloc(size_t dim)341 struct MultiApproxOpts * multi_approx_opts_alloc(size_t dim)
342 {
343     struct MultiApproxOpts * fargs;
344     if ( NULL == (fargs = malloc(sizeof(struct MultiApproxOpts)))){
345         fprintf(stderr, "Cannot allocate space for MultiApproxOpts.\n");
346         exit(1);
347     }
348     fargs->aopts = malloc(dim * sizeof(struct OneApproxOpts *));
349     if (fargs->aopts == NULL){
350         fprintf(stderr, "Cannot allocate MultiApproxOpts\n");
351         exit(1);
352     }
353     fargs->dim = dim;
354     for (size_t ii = 0; ii < dim; ii++){
355         fargs->aopts[ii] = NULL;
356     }
357 
358     return fargs;
359 }
360 
361 /***********************************************************//**
362     Free memory allocated to MultiApproxOpts (shallow)
363 
364     \param[in,out] fargs - function train approximation arguments
365 ***************************************************************/
multi_approx_opts_free(struct MultiApproxOpts * fargs)366 void multi_approx_opts_free(struct MultiApproxOpts * fargs)
367 {
368     if (fargs != NULL){
369         free(fargs->aopts); fargs->aopts = NULL;
370         free(fargs); fargs = NULL;
371     }
372 }
373 /***********************************************************//**
374     Free memory allocated to MultiApproxOpts (deep)
375 
376     \param[in,out] fargs - function train approximation arguments
377 ***************************************************************/
multi_approx_opts_free_deep(struct MultiApproxOpts ** fargs)378 void multi_approx_opts_free_deep(struct MultiApproxOpts ** fargs)
379 {
380     if (*fargs != NULL){
381         for (size_t ii = 0; ii < (*fargs)->dim; ii++){
382             printf("ii freeing deep %zu %d\n",ii, (*fargs)->aopts[ii] == NULL);
383            /* one_approx_opts_free((*fargs)->aopts[ii]); */
384             printf("here\n");
385             /* one_approx_opts_free_deep(&((*fargs)->aopts[ii])); */
386 
387             /* one_approx_opts_free((*fargs)->aopts[ii]); */
388             if ((*fargs)->aopts[ii] != NULL){
389                 free((*fargs)->aopts[ii]);
390                 ((*fargs)->aopts[ii]) = NULL;
391             }
392             printf("there\n");
393 
394             /*     free((*fargs)->aopts[ii]); */
395             /*     (*fargs)->aopts[ii] = NULL; */
396             /* } */
397         }
398         free((*fargs)->aopts); (*fargs)->aopts = NULL;
399         free(*fargs); *fargs = NULL;
400     }
401 }
402 
403 /***********************************************************//**
404     Set approximation options for a particular dimension
405     \param[in,out] fargs - function train approximation arguments
406     \param[in]     ind   - set approximation arguments for this dimension
407     \param[in]     opts  - approximation arguments
408 ***************************************************************/
multi_approx_opts_set_dim(struct MultiApproxOpts * fargs,size_t ind,struct OneApproxOpts * opts)409 void multi_approx_opts_set_dim(struct MultiApproxOpts * fargs,
410                                size_t ind,
411                                struct OneApproxOpts * opts)
412 {
413     assert (fargs != NULL);
414     assert (ind < fargs->dim);
415     fargs->aopts[ind] = opts;
416 }
417 
418 /***********************************************************//**
419     Set (by reference) approximation options for a particular value
420     \param[in,out] fargs - function train approximation arguments
421     \param[in]     ind   - set approximation arguments for this dimension
422     \param[in]     opts  - approximation arguments
423 ***************************************************************/
multi_approx_opts_set_dim_ref(struct MultiApproxOpts * fargs,size_t ind,struct OneApproxOpts ** opts)424 void multi_approx_opts_set_dim_ref(struct MultiApproxOpts * fargs,
425                                    size_t ind,
426                                    struct OneApproxOpts ** opts)
427 {
428     assert (fargs != NULL);
429     assert (ind < fargs->dim);
430     fargs->aopts[ind] = *opts;
431 }
432 
433 /***********************************************************//**
434     Create the arguments to give to use for approximation
435     in the function train. Specifically, legendre polynomials
436     for all dimensions
437 
438     \param[in,out] mopts - multidimensional options to update
439     \param[in]     opts  - options with which to update
440 
441 ***************************************************************/
442 void
multi_approx_opts_set_all_same(struct MultiApproxOpts * mopts,struct OneApproxOpts * opts)443 multi_approx_opts_set_all_same(struct MultiApproxOpts * mopts,
444                                struct OneApproxOpts * opts)
445 {
446     assert(mopts != NULL);
447     for (size_t ii = 0; ii < mopts->dim; ii++){
448         mopts->aopts[ii] = opts;
449     }
450 }
451 
452 /***********************************************************//**
453     Extract the function class to use for the approximation of the
454     *dim*-th dimensional functions
455 
456     \param[in] fargs - function train approximation arguments
457     \param[in] dim   - dimension to extract
458 
459     \return function_class of the approximation
460 ***************************************************************/
461 enum function_class
multi_approx_opts_get_fc(const struct MultiApproxOpts * fargs,size_t dim)462 multi_approx_opts_get_fc(const struct MultiApproxOpts * fargs, size_t dim)
463 {
464     return fargs->aopts[dim]->fc;
465 }
466 
467 /***********************************************************//**
468     Determine whether the unknowns for a particular dimension
469     are linearly related to the output
470 
471     \param[in] fargs - function train approximation arguments
472     \param[in] dim   - dimension to extract
473 
474     \return 1 if linear 0 if not linear
475 ***************************************************************/
multi_approx_opts_linear_p(const struct MultiApproxOpts * fargs,size_t dim)476 int multi_approx_opts_linear_p(const struct MultiApproxOpts * fargs, size_t dim)
477 {
478     return one_approx_opts_linear_p(fargs->aopts[dim]);
479 }
480 
481 /***********************************************************//**
482     Extract the approximation arguments to use for the approximation of the
483     *dim*-th dimensional functions
484 
485     \param[in] fargs - function train approximation arguments
486     \param[in] dim   - dimension to extract
487 
488     \return approximation arguments
489 ***************************************************************/
multi_approx_opts_get_aopts(const struct MultiApproxOpts * fargs,size_t dim)490 void * multi_approx_opts_get_aopts(const struct MultiApproxOpts * fargs,
491                                    size_t dim)
492 {
493     assert (fargs != NULL);
494     return fargs->aopts[dim];
495 }
496 
497 /***********************************************************//**
498     Get number of parameters requested by the approximation
499 
500     \param[in] f   - multi approx structure
501     \param[in] ind - which function to inquire about
502 ***************************************************************/
multi_approx_opts_get_dim_nparams(const struct MultiApproxOpts * f,size_t ind)503 size_t multi_approx_opts_get_dim_nparams(const struct MultiApproxOpts * f, size_t ind)
504 {
505     assert (f != NULL);
506     return one_approx_opts_get_nparams(f->aopts[ind]);
507 }
508 
509 /***********************************************************//**
510     Get the lower bounds of a particular dimension
511 
512     \param[in] f   - multi approx structure
513     \param[in] ind - which function to inquire about
514 ***************************************************************/
multi_approx_opts_get_dim_lb(const struct MultiApproxOpts * f,size_t ind)515 double multi_approx_opts_get_dim_lb(const struct MultiApproxOpts * f, size_t ind)
516 {
517     assert (f != NULL);
518     return one_approx_opts_get_lb(f->aopts[ind]);
519 }
520 
521 /***********************************************************//**
522     Get the upper bounds of a particular dimension
523 
524     \param[in] f   - multi approx structure
525     \param[in] ind - which function to inquire about
526 ***************************************************************/
multi_approx_opts_get_dim_ub(const struct MultiApproxOpts * f,size_t ind)527 double multi_approx_opts_get_dim_ub(const struct MultiApproxOpts * f, size_t ind)
528 {
529     assert (f != NULL);
530     return one_approx_opts_get_ub(f->aopts[ind]);
531 }
532 
533 /***********************************************************//**
534     Set the number of parameters
535 
536     \param[in,out] f   - multi approx structure
537     \param[in]     ind - which function to inquire about
538     \param[in]     val - new number of parameters
539 ***************************************************************/
multi_approx_opts_set_dim_nparams(struct MultiApproxOpts * f,size_t ind,size_t val)540 void multi_approx_opts_set_dim_nparams(struct MultiApproxOpts * f, size_t ind, size_t val)
541 {
542     assert (f != NULL);
543     one_approx_opts_set_nparams(f->aopts[ind],val);
544 }
545 
546 
547 /***********************************************************//**
548     Get the dimension
549 ***************************************************************/
multi_approx_opts_get_dim(const struct MultiApproxOpts * f)550 size_t multi_approx_opts_get_dim(const struct MultiApproxOpts * f)
551 {
552     assert (f != NULL);
553     return f->dim;
554 }
555 
556 ///////////////////////////////////////////////////////////////////
557 
558 struct FiberOptArgs
559 {
560     size_t dim;
561     void ** opts;
562 };
563 
564 
565 /***********************************************************//**
566   Allocate fiber optimization options
567 ***************************************************************/
fiber_opt_args_alloc()568 struct FiberOptArgs * fiber_opt_args_alloc()
569 {
570     struct FiberOptArgs * fopt = NULL;
571     fopt = malloc(sizeof(struct FiberOptArgs));
572     if (fopt == NULL){
573         fprintf(stderr,"Memory failure allocating FiberOptArgs\n");
574         exit(1);
575     }
576     return fopt;
577 }
578 
579 /***********************************************************//**
580     Initialize a baseline optimization arguments class
581 
582     \param[in] dim - dimension of problem
583 
584     \return fiber optimzation arguments that are NULL in each dimension
585 ***************************************************************/
fiber_opt_args_init(size_t dim)586 struct FiberOptArgs * fiber_opt_args_init(size_t dim)
587 {
588     struct FiberOptArgs * fopt = fiber_opt_args_alloc();
589     fopt->dim = dim;
590 
591     fopt->opts = malloc(dim * sizeof(void *));
592     if (fopt->opts == NULL){
593         fprintf(stderr,"Memory failure initializing fiber opt args\n");
594         exit(1);
595     }
596     for (size_t ii = 0; ii < dim; ii++){
597         fopt->opts[ii] = NULL;
598     }
599     return fopt;
600 }
601 
602 /***********************************************************//**
603    set optimization arguments to something
604 ***************************************************************/
fiber_opt_args_set_dim(struct FiberOptArgs * fopt,size_t ii,void * arg)605 void fiber_opt_args_set_dim(struct FiberOptArgs * fopt, size_t ii, void * arg)
606 {
607     assert (fopt != NULL);
608     assert (ii < fopt->dim);
609     fopt->opts[ii] = arg;
610 }
611 
612 /***********************************************************//**
613     Initialize a bruteforce optimization with the same nodes
614     in each dimension
615 
616     \param[in] dim   - dimension of problem
617     \param[in] nodes - nodes over which to optimize
618                        (same ones used for each dimension)
619 
620     \return fiber opt args
621 ***************************************************************/
622 struct FiberOptArgs *
fiber_opt_args_bf_same(size_t dim,struct c3Vector * nodes)623 fiber_opt_args_bf_same(size_t dim, struct c3Vector * nodes)
624 {
625     struct FiberOptArgs * fopt = fiber_opt_args_alloc();
626     fopt->dim = dim;
627 
628     fopt->opts = malloc(dim * sizeof(void *));
629     if (fopt->opts == NULL){
630         fprintf(stderr,"Memory failure initializing fiber opt args\n");
631         exit(1);
632     }
633     for (size_t ii = 0; ii < dim; ii++){
634         fopt->opts[ii] = nodes;
635     }
636     return fopt;
637 }
638 
639 /***********************************************************//**
640     Initialize a bruteforce optimization with different nodes
641     in each dimension
642 
643     \param[in] dim   - dimension of problem
644     \param[in] nodes - nodes over which to optimize
645                        (same ones used for each dimension)
646 
647     \return fiber opt args
648 ***************************************************************/
649 struct FiberOptArgs *
fiber_opt_args_bf(size_t dim,struct c3Vector ** nodes)650 fiber_opt_args_bf(size_t dim, struct c3Vector ** nodes)
651 {
652     struct FiberOptArgs * fopt = fiber_opt_args_alloc();
653     fopt->dim = dim;
654 
655     fopt->opts = malloc(dim * sizeof(void *));
656     if (fopt->opts == NULL){
657         fprintf(stderr,"Memory failure initializing fiber opt args\n");
658         exit(1);
659     }
660     for (size_t ii = 0; ii < dim; ii++){
661         fopt->opts[ii] = nodes[ii];
662     }
663     return fopt;
664 }
665 
666 /***********************************************************//**
667     Get optimization arguments for a certain dimension
668 
669     \param[in,out] fopts - fiber optimization structure
670     \param[in]     ind   - dimension
671 ***************************************************************/
fiber_opt_args_get_opts(const struct FiberOptArgs * fopts,size_t ind)672 void * fiber_opt_args_get_opts(const struct FiberOptArgs * fopts, size_t ind)
673 {
674     assert (fopts != NULL);
675     assert (ind < fopts->dim);
676     return fopts->opts[ind];
677 }
678 
679 /***********************************************************//**
680     Free memory allocate to fiber optimization arguments
681 
682     \param[in,out] fopt - fiber optimization structure
683 ***************************************************************/
fiber_opt_args_free(struct FiberOptArgs * fopt)684 void fiber_opt_args_free(struct FiberOptArgs * fopt)
685 {
686     if (fopt != NULL){
687         free(fopt->opts); fopt->opts = NULL;
688         free(fopt); fopt = NULL;
689     }
690 }
691 
692 
693