Révision 26

pobysoC-4.0/src/test/Makefile (revision 26)
1
CC           = gcc
2
CFLAGS       = -Wall -g  
3
LDLIB        = #-Wl,--verbose
4

  
5
OBJS         = 
6
INCS         = 
7
SOURCES      = $(INCS)
8

  
9
TEST_DRIVER  = # CUnit test driver binary program
10

  
11
ALL_TARGETS = 
12

  
13
SCRATCH_PRG := $(patsubst %.c,%,$(wildcard *.c))
14
SCRATCH_ALL := $(SCRATCH_PRG)
15

  
16
LAST_ARCH_FILE = lastArch.txt
17

  
18
ARCH := $(shell uname -m)
19

  
20
DUMMY := $(shell touch $(LAST_ARCH_FILE))
21

  
22
LAST_ARCH := $(shell cat $(LAST_ARCH_FILE))
23

  
24
ifneq ($(LAST_ARCH), $(ARCH))
25
  DUMMY := $(shell echo $(ARCH) > $(LAST_ARCH_FILE))
26
  DUMMY := $(shell $(MAKE) clean) 
27
endif
28

  
29
ifeq (x86_64, $(ARCH))
30
  CFLAGS := -m64 $(CFLAGS)
31
  # LDLIB :=
32
endif
33

  
34
ifeq (ppc64, $(ARCH))
35
  CFLAGS := -m64 $(CFLAGS)
36
  # LDLIB :=
37
endif
38

  
39
ifeq (i686, $(ARCH))
40
  # CFLAGS := $(CFLAGS)
41
  # LDLIB :=
42
endif
43

  
44
# -------------------------------------------------------------------------
45

  
46
default: all
47
# Remove all implicit (suffix) rules. No need to remove pattern rules.
48
# Just redefine them.
49
.SUFFIXES:
50
# Keep the OBJS we want to link with user code.
51
.PRECIOUS: $(OBJS)
52

  
53
all: $(ALL_TARGETS)
54
test: $(TEST_DRIVER)
55

  
56
% : %.o $(OBJS)
57
	$(CC) $(CFLAGS) -o $@ $< $(OBJS) $(LDLIB)
58

  
59
%.o : %.c $(INCS)
60
	$(CC) $(CFLAGS) -c -o $@ $<
61

  
62
$(TEST_DRIVER) : 
63
	make -C test
64
	cp test/$(TEST_DRIVER) .
65
# -------------------------------------------------------------------------
66

  
67
.PHONY: clean scratch
68

  
69
clean:
70
	@rm -f $(ALL_TARGETS) $(TEST_DRIVER)
71
	@rm -f *.o a.out $(OBJS)
72
	@rm -f *~ *% #*#
73

  
74
scratch: clean
75
	rm -f $(SCRATCH_ALL)
76

  
77
# Change the documentation configuration and path accordingly.
78
documentation: pobyso.doxyconf $(SOURCES)
79
	doxygen pobyso.doxyconf
0 80

  
pobysoC-4.0/src/pobyso.h (revision 26)
1
/** @file pobyso.h
2
 * Integration of Sollya to C programs
3
 * @author S.T.
4
 * @date 2011-10-11
5
 * Note: pobyso stands for POwered BY SOllya.
6
 *                         --      -- --
7
 */
8
/******************************************************************************/
9
 
10
/*
11
 * Add below all the headers needed to get this header work.
12
 */
13
/* <stdio.h> is needed *before* <mpfr.h> for all MPFR input/output functions
14
 * prototypes be defined. */
15
#include <stdio.h>
16
#include <sollya.h>
17
#include <mpfr.h>
18

  
19
#ifndef POBYSO_h
20

  
21
#define POBYSO_ABSOLUTE 1
22
#define POBYSO_RELATIVE 2
23
/* Mimic the default behavior of interactive Sollya. */
24
#define POBYSO_DEFAULT_POINTS 501
25
#define POBYSO_INF_NORM_NUM_POINTS (POBYSO_DEFAULT_POINTS)
26
#define POBYSO_GUESS_DEGREE_BOUND 1024
27

  
28
/**
29
 * Print object(s) to stdout.
30
 * A very thin wrapper around the lib_sollya_v_autoprint() function.
31
 * Should be called with NULL as the final argument.
32
 */
33
void
34
pobyso_autoprint(sollya_obj_t soObj, ...);
35

  
36
/**
37
 * Print object(s) to stdout: the va_list companion function.
38
 * A very thin wrapper around the lib_sollya_v_autoprint() function.
39
 * The last argument in the va_list should be NULL.
40
 */
41

  
42
void
43
pobyso_autoprint_v(sollya_obj_t soObj, va_list va);
44

  
45
/**
46
 * Parse a string to create a Sollya object.
47
 * A very thin wrapper around the sollya_lib_parse_string() function.
48
 */
49
sollya_obj_t
50
pobyso_parse_string(const char* expression);
51

  
52
/**
53
 * Set the verbosity mode off (level 0).
54
 * If currentVerbosity != NULL, currentVerbosity is set
55
 * to the current verbosity level. It may be used to reset the
56
 * verbosity level later.
57
 */
58
void
59
pobyso_set_verbosity_off(sollya_obj_t* currentVerbosityLevel);
60

  
61
/**
62
 * Set the verbosity level to newVerbosityLevel.
63
 * @param newVerbosityLevel must be a Sollay object corresponding to an
64
 *        integer constant.
65
 */
66
void
67
pobyso_set_verbosity_to(sollya_obj_t newVerbosityLevel);
68

  
69
#if 0
70
/**
71
 * Create the canonical (non sparse) base of monomials for a given degree.
72
 */
73
chain*
74
pobyso_create_canonical_monomials_base(const unsigned int degree);
75

  
76
/**
77
 * Create a chain from an array of int.
78
 */
79
sollya_int_list
80
pobyso_create_int_list_from_int_Array(int* intArray,
81
                                    const unsigned int arrayLength);
82

  
83
/**
84
 * Create a chain from an array of int.
85
 */
86
sollya_int_list_t
87
pobyso_create_int_list_from_unsigned_int_array(unsigned int* intArray,
88
                                            const unsigned int arrayLength);
89
/**
90
 * Differentiation of a function.
91
 * A slim wrapper around the Sollya differentiate function.
92
 * @param functionNode - the Sollya node to differentiate;
93
 * @return a node representing the function differentiated or NULL, if
94
 *         something goes wrong.
95
 */
96

  
97
sollya_obj_t
98
pobyso_diff(sollya_obj_t function);
99

  
100
/**
101
 * A match to the Sollya dirtyinfnorm.
102
 * A slim wrapper around the Sollya function.
103
 * @param infnorm - out parameter to return the result, must be "inited"
104
 *                  and "cleared" by the caller;
105
 * @param functionNode - the Sollya node to compute the infinite norm of;
106
 * @param lowerBound - the lower bound of the interval;
107
 * @param upperBound - the upper bound of the interval;
108
 * @param precision  - the internal precision Sollya must use.
109
 * @return 0 if everything is OK, != 0 if something goes wrong.
110
 */
111
int
112
pobyso_dirty_infnorm(mpfr_t infNorm,
113
                      node *functionNode,
114
                      mpfr_t lowerBound,
115
                      mpfr_t upperBound,
116
                      mp_prec_t precision);
117

  
118

  
119
/**
120
 * Faithful evaluation of an expression.
121
 *
122
 * @param faitufulEvaluation - holds the result, must be "inited" by the
123
 *                             caller;
124
 */
125
int
126
pobyso_evaluate_faithful(mpfr_t faithfulEvaluation,
127
                          node *nodeToEvaluate,
128
                          mpfr_t argument,
129
                          mpfr_prec_t precision);
130

  
131
/**
132
 * Find the zeros of a function on a given interval.
133
 */
134
chain*
135
pobyso_find_zeros(node *function,
136
                  mpfr_t *lowerBound,
137
                  mpfr_t *upperBound);
138
/**
139
 * Free a chain of node.
140
 * All elements of the chain have to be nodes.
141
 */
142
void
143
pobyso_free_chain_of_nodes(chain *theChain);
144

  
145
/**
146
 * Free a range.
147
 * It involves clearing the mpfr_t elements and deallocating the
148
 * pointers.
149
 */
150
void
151
pobyso_free_range(rangetype range);
152

  
153
/**
154
 * Computes a good polynomial approximation with fixed-point or floating-point
155
 * coefficients.
156
 */
157
node*
158
pobyso_fp_minimax_canonical_monomials_base(node *function,
159
                                          int degree,
160
                                          chain *formats,
161
                                          chain *points,
162
                                          mpfr_t lowerBound,
163
                                          mpfr_t upperBound,
164
                                          int fpFixedArg,
165
                                          int absRel,
166
                                          node *constPart,
167
                                          node *minimax);
168
/**
169
 * Parses a string to build the node representing the function.
170
 * In fact, does nothing for the moment: the string must be a correct function
171
 * definition. No error correction takes place here.
172
 */
173
node*
174
pobyso_parse_function(char *functionString,
175
                      char *freeVariableNameString);
176

  
177
/** Compute a polynomial approximation in the canonical monomials basis for
178
 *  a function, for a given precision. The returned polynomial has the minimal
179
 *  degree to achieve the required precision.
180
 */
181
node*
182
pobyso_remez_approx_canonical_monomials_base_for_error(node *functionNode,
183
                                                      unsigned int mode,
184
                                                      mpfr_t lowerBound,
185
                                                      mpfr_t upperBound,
186
                                                      mpfr_t eps);
187

  
188
/**
189
 * Computes a the remez approximation of a function.
190
 * @param function   - the node holding the function to approximate;
191
 * @param weight     - the node holding the weight function, can be NULL. In
192
 *                     this case a default weight of "1" will be provided and
193
 *                     the approximation is related is with respect to the
194
 *                     absolute error.
195
 * @param degree     - the degree of the approximation polynomial;
196
 * @param lowerBound - the lower bound of the approximation interval;
197
 * @param upperBound - the upper bound of the approximation interval;
198
 * @param quality    - quality = (eps - eps*) / eps*; the search stop when the required
199
 *                     quality is achieved.
200
 *
201
 * @return a node holding the approximation polynomial in Horner form.
202
 */
203
node*
204
pobyso_remez_canonical_monomials_base(node *function,
205
                                       node *weight,
206
                                       unsigned int degree,
207
                                       mpfr_t lowerBound,
208
                                       mpfr_t upperBound,
209
                                       mpfr_t quality);
210
#endif
211
#define POBYSO_h  
212
  
213
#endif
214
  
0 215

  
pobysoC-4.0/src/pobyso.c (revision 26)
1
/** @file pobyso.c
2
 * Name & purpose
3
 *
4
 * @author S.T.
5
 * @date 2011-10-12
6
 *
7
 */
8
/******************************************************************************/
9
/* Headers, applying the "particular to general" convention.*/
10

  
11
#include "pobyso.h"
12

  
13
/* includes of local headers */
14

  
15
/* includes of project headers */
16

  
17
/* includes of system headers */
18

  
19
/* Other declarations */
20

  
21
/* Internal prototypes */
22
void
23
pobyso_error_message(char *functionName, char *messageName, char* message);
24
/* Types, constants and macros definitions */
25

  
26
/* Global variables */
27

  
28
/* Functions */
29
void
30
pobyso_autoprint(sollya_obj_t solObj, ...)
31
{
32
  va_list va;
33
  va_start(va, solObj);
34
  sollya_lib_v_autoprint(solObj, va);
35
  va_end(va);
36
} /* End pobyso_autoprint. */
37

  
38
sollya_obj_t
39
pobyso_parse_string(const char* expression)
40
{
41
  if (expression == NULL)
42
  {
43
    pobyso_error_message("pobyso_parse_string",
44
                        "NULL_POINTER_ARGUMENT",
45
                        "The expression is a NULL pointer");
46
    return(NULL);
47
  }
48
  return(sollya_lib_parse_string(expression));
49
} /* pobyso_parse_string */
50

  
51
void
52
pobyso_set_verbosity_off(sollya_obj_t* currentVerbosityLevel)
53
{
54
  sollya_obj_t verbosityLevelZero;
55
  if (currentVerbosityLevel != NULL)
56
  {
57
     *currentVerbosityLevel = sollya_lib_get_verbosity();
58
  }
59
  verbosityLevelZero = sollya_lib_constant_from_int(0);
60
  sollya_lib_set_verbosity(verbosityLevelZero);
61
  sollya_lib_clear_obj(verbosityLevelZero);
62
} /* End of pobyso_set_verbosity_off. */
63

  
64
void
65
pobyso_set_verbosity_to(sollya_obj_t newVerbosityLevel)
66
{
67
  if (newVerbosityLevel == NULL)
68
  {
69
    pobyso_error_message("pobyso_set_verbosity_to",
70
                        "NULL_POINTER_ARGUMENT",
71
                        "The new verbosity level is a NULL pointer");
72
    return;
73
  }
74
  sollya_lib_set_verbosity(newVerbosityLevel);
75
} /* End of pobyso_set_verbosity_to. */
76

  
77
/* Attic from the sollya_lib < 4. */
78
#if 0
79
chain*
80
pobyso_create_canonical_monomials_base(const unsigned int degree)
81
{
82
  int i    = 0;
83
  chain *monomials  = NULL;
84
  node  *monomial   = NULL;
85

  
86
  for(i = degree ; i >= 0  ; i--)
87
  {
88
     monomial   = makePow(makeVariable(), makeConstantDouble((double)i));
89
     monomials  = addElement(monomials, monomial);
90
     fprintf(stderr, "pobyso_create_canonical_monomials_base: %u\n", i);
91
  }
92
  if (monomials == NULL)
93
  {
94
    pobyso_error_message("pobyso_create_canonical_monomial_base",
95
                        "CHAIN_CREATION_ERROR",
96
                        "Could not create the monomials chain");
97
    return(NULL);
98
  }
99
  return(monomials);
100
} /* End pobyso_create_canonical_monomials_base. */
101

  
102
chain*
103
pobyso_create_chain_from_int_array(int* intArray,
104
                                    const unsigned int arrayLength)
105
{
106
  int i = 0;
107
  chain *newChain = NULL;
108
  int *currentInt;
109

  
110
  if (arrayLength == 0) return(NULL);
111
  if (intArray == NULL)
112
  {
113
    pobyso_error_message("pobyso_create_chain_from_int_array",
114
                        "NULL_POINTER_ARGUMENT",
115
                        "The array is a NULL pointer");
116
    return(NULL);
117
  }
118
  for (i = arrayLength - 1 ; i >= 0 ; i--)
119
  {
120
    currentInt = malloc(sizeof(int));
121
    if (currentInt == NULL)
122
    {
123
      pobyso_error_message("pobyso_create_chain_from_int_array",
124
                          "MEMORY_ALLOCATION_ERROR",
125
                          "Could not allocate one of the integers");
126
      freeChain(newChain, free);
127
      return(NULL);
128
    }
129
    *currentInt = intArray[i];
130
    newChain = addElement(newChain, currentInt);
131
  }
132
  return(newChain);
133
} // End pobyso_create_chain_from_int_array. */
134

  
135
chain*
136
pobyso_create_chain_from_unsigned_int_array(unsigned int* intArray,
137
                                        const unsigned int arrayLength)
138
{
139
  int i = 0;
140
  chain *newChain = NULL;
141
  unsigned int *currentInt;
142

  
143
  /* Argument checking. */
144
  if (arrayLength == 0) return(NULL);
145
  if (intArray == NULL)
146
  {
147
    pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
148
                        "NULL_POINTER_ARGUMENT",
149
                        "The array is a NULL pointer");
150
    return(NULL);
151
  }
152
  for (i = arrayLength - 1 ; i >= 0 ; i--)
153
  {
154
    currentInt = malloc(sizeof(unsigned int));
155
    if (currentInt == NULL)
156
    {
157
      pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
158
                          "MEMORY_ALLOCATION_ERROR",
159
                          "Could not allocate one of the integers");
160
      freeChain(newChain, free);
161
      return(NULL);
162
    }
163
    *currentInt = intArray[i];
164
    newChain = addElement(newChain, currentInt);
165
  }
166
  return(newChain);
167
} // End pobyso_create_chain_from_unsigned_int_array. */
168

  
169
node*
170
pobyso_differentiate(node *functionNode)
171
{
172
  /* Argument checking. */
173
  node *differentialNode;
174
  if (functionNode == NULL)
175
  {
176
    pobyso_error_message("pobyso_differentiate",
177
                        "NULL_POINTER_ARGUMENT",
178
                        "The function to differentiate is a NULL pointer");
179
    return(NULL);
180
  }
181
  differentialNode = differentiate(functionNode);
182
  if (differentialNode == NULL)
183
  {
184
    pobyso_error_message("pobyso_differentiate",
185
                        "INTERNAL ERROR",
186
                        "Sollya could not differentiate the function");
187
  }
188
  return(differentialNode);
189
} // End pobyso_differentiate
190

  
191

  
192
int
193
pobyso_dirty_infnorm(mpfr_t infNorm,
194
                      node *functionNode,
195
                      mpfr_t lowerBound,
196
                      mpfr_t upperBound,
197
                      mp_prec_t precision)
198
{
199
  int functionCallResult;
200
  /* Arguments checking. */
201
  if (functionNode == NULL)
202
  {
203
    pobyso_error_message("pobyso_dirty_infnorm",
204
                        "NULL_POINTER_ARGUMENT",
205
                        "The function to compute is a NULL pointer");
206
    return(1);
207
  }
208
  if (mpfr_cmp(lowerBound, upperBound) > 0)
209
  {
210
    pobyso_error_message("pobyso_dirty_infnorm",
211
                        "INCOHERENT_INPUT_DATA",
212
                        "The lower bond is greater than the upper bound");
213
    return(1);
214
  }
215
  /* Particular cases. */
216
  if (mpfr_cmp(lowerBound, upperBound) == 0)
217
  {
218
    functionCallResult = pobyso_evaluate_faithful(infNorm,
219
                                                  functionNode,
220
                                                  lowerBound,
221
                                                  precision);
222
    return(functionCallResult);
223
  }
224
  if (isConstant(functionNode))
225
  {
226
    functionCallResult = pobyso_evaluate_faithful(infNorm,
227
                                                  functionNode,
228
                                                  lowerBound,
229
                                                  precision);
230
    if (!functionCallResult)
231
    {
232
      mpfr_abs(infNorm, infNorm, MPFR_RNDN);
233
    }
234
    return(functionCallResult);
235
  }
236
  uncertifiedInfnorm(infNorm,
237
                      functionNode,
238
                      lowerBound,
239
                      upperBound,
240
                      POBYSO_DEFAULT_POINTS,
241
                      precision);
242
  return(0);
243
} /* End pobyso_dirty_infnorm. */
244

  
245
int
246
pobyso_evaluate_faithful(mpfr_t faithfulEvaluation,
247
                          node *nodeToEvaluate,
248
                          mpfr_t argument,
249
                          mpfr_prec_t precision)
250
{
251
  /* Check input arguments. */
252
  if (nodeToEvaluate == NULL)
253
  {
254
    pobyso_error_message("pobyso_evaluate_faithful",
255
                        "NULL_POINTER_ARGUMENT",
256
                        "nodeToEvaluate is a NULL pointer");
257
    return(1);
258
  }
259
  evaluateFaithful(faithfulEvaluation,
260
                   nodeToEvaluate,
261
                   argument,
262
                   precision);
263
  return(0);
264
} /* End pobyso_evaluate_faithfull. */
265

  
266
chain*
267
pobyso_find_zeros(node *function,
268
                  mpfr_t *lower_bound,
269
                  mpfr_t *upper_bound)
270
{
271
  mp_prec_t currentPrecision;
272
  mpfr_t currentDiameter;
273
  rangetype bounds;
274

  
275
  currentPrecision = getToolPrecision();
276
  mpfr_init2(currentDiameter, currentPrecision);
277

  
278
  bounds.a = lower_bound;
279
  bounds.b = upper_bound;
280

  
281
  if (bounds.a == NULL || bounds.b == NULL)
282
  {
283
    pobyso_error_message("pobyso_find_zeros",
284
                        "MEMORY_ALLOCATION_ERROR",
285
                        "Could not allocate one of the bounds");
286
    return(NULL);
287
  }
288
  return(findZerosFunction(function,
289
                            bounds,
290
                            currentPrecision,
291
                            currentDiameter));
292
} /* End pobyso_find_zeros. */
293

  
294
void
295
pobyso_free_chain_of_nodes(chain *theChainOfNodes)
296
{
297
  node *currentNode           = NULL;
298
  chain *currentChainElement  = NULL;
299
  chain *nextChainElement     = NULL;
300

  
301
  nextChainElement = theChainOfNodes;
302

  
303
  while(nextChainElement != NULL)
304
  {
305
    currentChainElement = nextChainElement;
306
    currentNode = (node*)(currentChainElement->value);
307
    nextChainElement = nextChainElement->next;
308
    free_memory(currentNode);
309
    free((void*)(currentChainElement));
310
  }
311
} /* End pobyso_free_chain_of_nodes. */
312

  
313
void
314
pobyso_free_range(rangetype range)
315
{
316

  
317
  mpfr_clear(*(range.a));
318
  mpfr_clear(*(range.b));
319
  free(range.a);
320
  free(range.b);
321
} /* End pobyso_free_range. */
322

  
323
node*
324
pobyso_fp_minimax_canonical_monomials_base(node *function,
325
                                      int degree,
326
                                      chain *formats,
327
                                      chain *points,
328
                                      mpfr_t lowerBound,
329
                                      mpfr_t upperBound,
330
                                      int fpFixedArg,
331
                                      int absRel,
332
                                      node *constPart,
333
                                      node *minimax)
334
{
335
  return(NULL);
336
} /* End pobyso_fp_minimax_canonical_monomials_base. */
337

  
338
node*
339
pobyso_parse_function(char *functionString,
340
                      char *freeVariableNameString)
341
{
342
  if (functionString == NULL || freeVariableNameString == NULL)
343
  {
344
    pobyso_error_message("pobyso_parse_function",
345
                        "NULL_POINTER_ARGUMENT",
346
                        "One of the arguments is a NULL pointer");
347
    return(NULL);
348
  }
349
  return(parseString(functionString));
350

  
351
} /* End pobyso_parse_function */
352

  
353
node*
354
pobyso_remez_approx_canonical_monomials_base_for_error(node *functionNode,
355
                                                  unsigned int mode,
356
                                                  mpfr_t lowerBound,
357
                                                  mpfr_t upperBound,
358
                                                  mpfr_t eps)
359
{
360
  node *weight              = NULL;
361
  node *bestApproxPolyNode  = NULL;
362
  node *bestApproxHorner    = NULL;
363
  node *errorNode           = NULL;
364
  rangetype degreeRange;
365
  mpfr_t quality;
366
  mpfr_t currentError;
367
  unsigned int degree;
368

  
369
  /* Check the parameters. */
370
  if (functionNode == NULL)
371
  {
372
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
373
                        "NULL_POINTER_ARGUMENT",
374
                        "functionNode is a NULL pointer");
375
    return(NULL);
376
  }
377
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
378
  {
379
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
380
                        "INCOHERENT_INPUT_DATA",
381
                        "the lower_bound >= upper_bound");
382
    return(NULL);
383
  }
384
  /* Set the weight. */
385
  if (mode == POBYSO_ABSOLUTE)
386
  {
387
    /* Set the weight to 1 for the ABSOLUTE_MODE. */
388
    weight = makeConstantDouble(1.0);
389
  }
390
  else
391
  {
392
    if (mode == POBYSO_RELATIVE)
393
    {
394
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
395
                          "NOT_IMPLEMENTED",
396
                          "the search for relative error is not implemented yet");
397
      return(NULL);
398
    }
399
    else
400
    {
401
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
402
                          "INCOHERENT_INPUT_DATA",
403
                          "the mode is node of POBYSO_ABOLUTE or POBYSO_RELATIVE");
404
      return(NULL);
405
    }
406
  }
407
  //fprintf(stderr, "\n\n\n******* I'm here! ********\n\n\n");
408
  degreeRange = guessDegree(functionNode,
409
                            weight,
410
                            lowerBound,
411
                            upperBound,
412
                            eps,
413
                            POBYSO_GUESS_DEGREE_BOUND);
414
  degree = mpfr_get_ui(*(degreeRange.a), MPFR_RNDN);
415
  //fprintf(stderr, "\n\n\n******* I'm back! ********\n\n\n");
416
  fprintf(stderr, "Guessed degree: ");
417
  mpfr_out_str(stderr, 10, 17, *(degreeRange.a), MPFR_RNDN);
418
  fprintf(stderr, " - as int: %u\n", degree);
419
  /* Reduce the degree by 1 in the foolish hope it could work. */
420
  if (degree > 0) degree--;
421
  /* Both elements of degreeRange where "inited" within guessDegree. */
422
  mpfr_clear(*(degreeRange.a));
423
  mpfr_clear(*(degreeRange.b));
424
  free(degreeRange.a);
425
  free(degreeRange.b);
426
  /* Mimic the default behavior of interactive Sollya. */
427
  mpfr_init(quality);
428
  mpfr_set_d(quality, 1e-5, MPFR_RNDN);
429
  mpfr_init2(currentError, getToolPrecision());
430
  mpfr_set_inf(currentError,1);
431

  
432
  /* Try to refine the initial guess: loop with increasing degrees until
433
   * we find a satisfactory one. */
434
  while(mpfr_cmp(currentError, eps) > 0)
435
  {
436
    /* Get rid of the previous polynomial, if any. */
437
    if (bestApproxPolyNode != NULL)
438
    {
439
      free_memory(bestApproxPolyNode);
440
    }
441
    fprintf(stderr, "Degree: %u\n", degree);
442
    fprintf(stderr, "Calling pobyso_remez_canonical_monomials_base...\n");
443
    /* Try to find a polynomial with the guessed degree. */
444
    bestApproxPolyNode = pobyso_remez_canonical_monomials_base(functionNode,
445
                                                            weight,
446
                                                            degree,
447
                                                            lowerBound,
448
                                                            upperBound,
449
                                                            quality);
450

  
451
    if (bestApproxPolyNode == NULL)
452
    {
453
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
454
                          "INTERNAL_ERROR",
455
                          "could not compute the bestApproxPolyNode");
456
      mpfr_clear(currentError);
457
      mpfr_clear(quality);
458
      return(NULL);
459
    }
460

  
461
    setDisplayMode(DISPLAY_MODE_DECIMAL);
462
    fprintTree(stderr, bestApproxPolyNode);
463
    fprintf(stderr, "\n\n");
464

  
465
    errorNode = makeSub(copyTree(functionNode), copyTree(bestApproxPolyNode));
466
    /* Check the error with the computed polynomial. */
467
    uncertifiedInfnorm(currentError,
468
                        errorNode,
469
                        lowerBound,
470
                        upperBound,
471
                        POBYSO_INF_NORM_NUM_POINTS,
472
                        getToolPrecision());
473
    fprintf(stderr, "Inf norm: ");
474
    mpfr_out_str(stderr, 10, 17, currentError, MPFR_RNDN);
475
    fprintf(stderr, "\n\n");
476
    /* Free the errorNode but not the bestApproxPolyNode (we need it if
477
     * we exit the loop at the next iteration). */
478
    free_memory(errorNode);
479
    degree++;
480
  }
481
  /* Use an intermediate variable, since horner() creates a new node
482
   * and does not reorder the argument "in place". This allows for the memory
483
   * reclaim of bestApproxHorner.
484
   */
485
  bestApproxHorner = horner(bestApproxPolyNode);
486
  free_memory(bestApproxPolyNode);
487
  mpfr_clear(currentError);
488
  mpfr_clear(quality);
489
  free_memory(weight);
490
  return(bestApproxHorner);
491
} /* End pobyso_remez_approx_canonical_monomials_base_for_error */
492

  
493
node*
494
pobyso_remez_canonical_monomials_base(node *function,
495
                                     node *weight,
496
                                     unsigned int degree,
497
                                     mpfr_t lowerBound,
498
                                     mpfr_t upperBound,
499
                                     mpfr_t quality)
500
{
501
  node  *bestApproxPoly = NULL;
502
  chain *monomials      = NULL;
503
  chain *curMonomial    = NULL;
504

  
505
  mpfr_t satisfying_error;
506
  mpfr_t target_error;
507

  
508
  /* Argument checking */
509
  /* Function tree. */
510
  if (function == NULL)
511
  {
512
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
513
                        "NULL_POINTER_ARGUMENT",
514
                        "the \"function\" argument is a NULL pointer");
515
    return(NULL);
516
  }
517
  if (weight == NULL)
518
  {
519
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
520
                        "NULL_POINTER_ARGUMENT",
521
                        "the \"weight\" argument is a NULL pointer");
522
    return(NULL);
523
  }
524
  /* Check the bounds. */
525
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
526
  {
527
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
528
                        "INCOHERENT_IMPUT_DATA",
529
                        "the lower_bound >= upper_bound");
530
    return(NULL);
531
  }
532
  /* The quality must be a non null positive number. */
533
  if (mpfr_sgn(quality) <= 0)
534
  {
535
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
536
                        "INCOHERENT_INPUT_DATA",
537
                        "the quality <= 0");
538
  }
539
  /* End argument checking. */
540
  /* Create the monomials nodes chains. */
541
  monomials = pobyso_create_canonical_monomials_base(degree);
542
  fprintf(stderr, "monomials chain length = %d\n", lengthChain(monomials));
543
  if (monomials == NULL || (lengthChain(monomials) != degree + 1))
544
  {
545
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
546
                        "CHAIN_CREATION_ERROR",
547
                        "could not create the monomials chain");
548
    return(NULL);
549
  }
550
  curMonomial = monomials;
551

  
552
  while (curMonomial != NULL)
553
  {
554
    fprintf(stderr, "monomial tree: ");
555
    //mpfr_out_str(stderr, 10, 17, *((mpfr_t*)((node*)(curMonomial->value))->value), MPFR_RNDN);
556
    fprintTree(stderr, (node*)(curMonomial->value));
557
    fprintf(stderr, "\n");
558
    curMonomial = curMonomial->next;
559
  }
560

  
561
  /* Deal with NULL weight. */
562
  if (weight == NULL)
563
  {
564
    weight = makeConstantDouble(1.0);
565
  }
566
  /* Compute the best polynomial with the required quality.
567
     The behavior is as if satisfying error and target_error had
568
     not been used.*/
569
  mpfr_init(satisfying_error);
570
  mpfr_init(target_error);
571
  mpfr_set_str(satisfying_error, "0", 10, MPFR_RNDN);
572
  mpfr_set_inf(target_error, 1);
573

  
574

  
575
  fprintf(stderr, "satisfying_error: ");
576
  mpfr_out_str(stderr, 10, 17, satisfying_error, MPFR_RNDN);
577
  fprintf(stderr, ".\n");
578
  fprintf(stderr, "target_error: ");
579
  mpfr_out_str(stderr, 10, 17, target_error,MPFR_RNDN);
580
  fprintf(stderr, ".\n");
581

  
582
  fprintf(stderr,
583
          "current precision: %li\n", getToolPrecision());
584
  /* Call the Sollya function. */
585
  bestApproxPoly = remez(function,
586
                          weight,
587
                          monomials,
588
                          lowerBound,
589
                          upperBound,
590
                          quality,
591
                          satisfying_error,
592
                          target_error,
593
                          getToolPrecision());
594

  
595
  mpfr_clear(satisfying_error);
596
  mpfr_clear(target_error);
597
  pobyso_free_chain_of_nodes(monomials);
598

  
599
  return(bestApproxPoly);
600
} /* End pobyso_remez_canonical_monomials_base. */
601

  
602
#endif
603

  
604
void
605
pobyso_error_message(char *functionName, char *messageName, char* message)
606
{
607
  fprintf(stderr, "?%s: %s.\n%s.\n", functionName, messageName, message);
608
} /* End pobyso_error_message */
0 609

  
pobysoC-4.0/src/Makefile (revision 26)
1
CC           = gcc
2
CFLAGS       = -Wall -g -I /warehouse/storres/root/include
3
LDLIB        = #-Wl,--verbose
4

  
5
OBJS         = pobyso.o
6
INCS         = pobyso.h 
7
SOURCES      = $(INCS) pobyso.c
8

  
9
TEST_DRIVER  = # CUnit test driver binary program
10
TEST_DIR     = test
11
TEST_SOURCES = $(TEST_DIR)/$(TEST_DRIVER).c \
12
               # Add the suites definition sources
13

  
14
ALL_TARGETS = pobyso.o
15

  
16
SCRATCH_PRG := $(patsubst %.c,%,$(wildcard *.c))
17
SCRATCH_ALL := $(SCRATCH_PRG)
18

  
19
LAST_ARCH_FILE = lastArch.txt
20

  
21
ARCH := $(shell uname -m)
22

  
23
DUMMY := $(shell touch $(LAST_ARCH_FILE))
24

  
25
LAST_ARCH := $(shell cat $(LAST_ARCH_FILE))
26

  
27
ifneq ($(LAST_ARCH), $(ARCH))
28
  DUMMY := $(shell echo $(ARCH) > $(LAST_ARCH_FILE))
29
  DUMMY := $(shell $(MAKE) clean) 
30
endif
31

  
32
ifeq (x86_64, $(ARCH))
33
  CFLAGS := -m64 $(CFLAGS)
34
  # LDLIB :=
35
endif
36

  
37
ifeq (ppc64, $(ARCH))
38
  CFLAGS := -m64 $(CFLAGS)
39
  # LDLIB :=
40
endif
41

  
42
ifeq (i686, $(ARCH))
43
  # CFLAGS := $(CFLAGS)
44
  # LDLIB :=
45
endif
46

  
47
# -------------------------------------------------------------------------
48

  
49
default: all
50
# Remove all implicit (suffix) rules. No need to remove pattern rules.
51
# Just redefine them.
52
.SUFFIXES:
53
# Keep the OBJS we want to link with user code.
54
.PRECIOUS: $(OBJS)
55

  
56
all: $(ALL_TARGETS)
57
test: $(TEST_DRIVER)
58

  
59
% : %.o $(OBJS)
60
	$(CC) $(CFLAGS) -o $@ $< $(OBJS) $(LDLIB)
61

  
62
%.o : %.c $(INCS)
63
	$(CC) $(CFLAGS) -c -o $@ $<
64

  
65
$(TEST_DRIVER) : 
66
	make -C test
67
	cp test/$(TEST_DRIVER) .
68
# -------------------------------------------------------------------------
69

  
70
.PHONY: clean scratch
71

  
72
clean:
73
	@rm -f $(ALL_TARGETS) $(TEST_DRIVER)
74
	@rm -f *.o a.out $(OBJS)
75
	@rm -f *~ *% #*#
76
	@make -C $(TEST_DIR) clean
77

  
78
scratch: clean
79
	rm -f $(SCRATCH_ALL)
80

  
81
# Change the documentation configuration and path accordingly.
82
documentation: pobyso.doxyconf $(SOURCES)
83
	doxygen pobyso.doxyconf
0 84

  

Formats disponibles : Unified diff