Statistiques
| Révision :

root / pobysoC-4.0 / src / pobyso.c @ 134

Historique | Voir | Annoter | Télécharger (27,3 ko)

1 26 storres
/** @file pobyso.c
2 26 storres
 * Name & purpose
3 26 storres
 *
4 26 storres
 * @author S.T.
5 26 storres
 * @date 2011-10-12
6 26 storres
 *
7 27 storres
 *
8 26 storres
 */
9 50 storres
10 26 storres
/******************************************************************************/
11 26 storres
/* Headers, applying the "particular to general" convention.*/
12 26 storres
13 26 storres
#include "pobyso.h"
14 26 storres
15 26 storres
/* includes of local headers */
16 26 storres
17 26 storres
/* includes of project headers */
18 26 storres
19 26 storres
/* includes of system headers */
20 128 storres
#include <string.h>
21 128 storres
#include <stdlib.h>
22 128 storres
#include <stdio.h>
23 26 storres
24 26 storres
/* Other declarations */
25 26 storres
26 26 storres
/* Internal prototypes */
27 26 storres
void
28 26 storres
pobyso_error_message(char *functionName, char *messageName, char* message);
29 26 storres
/* Types, constants and macros definitions */
30 26 storres
31 26 storres
/* Global variables */
32 26 storres
33 26 storres
/* Functions */
34 127 storres
35 134 storres
/* @see pobyso.h#pobyso_autoprint */
36 26 storres
void
37 134 storres
pobyso_autoprint(sollya_obj_t solObj)
38 26 storres
{
39 134 storres
  sollya_lib_autoprint(solObj, NULL);
40 26 storres
} /* End pobyso_autoprint. */
41 26 storres
42 134 storres
/* @see pobyso.h#pobyso_get_verbosity */
43 134 storres
int
44 134 storres
pobyso_get_verbosity()
45 134 storres
{
46 134 storres
  sollya_obj_t verbositySo = NULL;
47 134 storres
  int verbosity            = 0;
48 134 storres
49 134 storres
  verbositySo = sollya_lib_get_verbosity();
50 134 storres
  sollya_lib_get_constant_as_int(&verbosity,verbositySo);
51 134 storres
  sollya_lib_clear_obj(verbositySo);
52 134 storres
  return verbosity;
53 134 storres
} /* End pobyso_get_verbosity. */
54 134 storres
55 133 storres
/* @see pobyso.h#pobyso_is_constant_expression*/
56 133 storres
int
57 133 storres
pobyso_is_constant_expression(sollya_obj_t obj_to_test)
58 133 storres
{
59 133 storres
  mpfr_t dummy;
60 133 storres
  int test;
61 134 storres
  int initial_verbosity_level      = 0;
62 134 storres
63 133 storres
  /* Test argument. */
64 133 storres
  if (obj_to_test == NULL)
65 133 storres
  {
66 133 storres
    pobyso_error_message("pobyso_parse_string",
67 133 storres
                        "NULL_POINTER_ARGUMENT",
68 133 storres
                        "The expression is a NULL pointer");
69 133 storres
    return 0;
70 133 storres
  }
71 134 storres
  initial_verbosity_level = pobyso_set_verbosity_off();
72 128 storres
73 133 storres
  if (! sollya_lib_obj_is_function(obj_to_test))
74 133 storres
  {
75 134 storres
    pobyso_set_verbosity_to(initial_verbosity_level);
76 133 storres
    return 0;
77 133 storres
  }
78 133 storres
  mpfr_init2(dummy,64);
79 133 storres
  /* Call to previous Sollya function resets verbosity. */
80 134 storres
  pobyso_set_verbosity_off();
81 133 storres
  test = sollya_lib_get_constant(dummy, obj_to_test);
82 133 storres
  mpfr_clear(dummy);
83 134 storres
  pobyso_set_verbosity_to(initial_verbosity_level);
84 133 storres
  return test;
85 133 storres
} /* End pobyso_is_constant_expression. */
86 133 storres
87 133 storres
/** @see pobyso.h#pobyso_new_monomial. */
88 133 storres
pobyso_func_exp_t
89 134 storres
pobyso_new_monomial(pobyso_func_exp_t coefficientSo, long degree)
90 133 storres
{
91 134 storres
  sollya_obj_t degreeSo   = NULL;
92 134 storres
  sollya_obj_t varToPowSo = NULL;
93 134 storres
  sollya_obj_t monomialSo = NULL;
94 134 storres
  int initial_verbosity_level = 0;
95 134 storres
96 134 storres
  /* Arguments check. */
97 134 storres
  if (coefficientSo == NULL)
98 133 storres
  {
99 133 storres
    pobyso_error_message("pobyso_parse_string",
100 133 storres
                        "NULL_POINTER_ARGUMENT",
101 133 storres
                        "The expression is a NULL pointer");
102 134 storres
    return NULL;
103 133 storres
  }
104 134 storres
  if (! pobyso_is_constant_expression(coefficientSo))
105 133 storres
  {
106 134 storres
    return NULL;
107 133 storres
  }
108 133 storres
  if (degree < 0)
109 133 storres
  {
110 134 storres
    pobyso_error_message("pobyso_new_monomial",
111 134 storres
                        "NEGATIVE_DEGREE_ARGUMENT",
112 134 storres
                        "The degree is a negative integer");
113 134 storres
    return NULL;
114 133 storres
  }
115 134 storres
  /* If degree == 0, just return a copy of the coefficient. Do not
116 134 storres
   * return the coefficient itself to avoid "double clear" issues. */
117 134 storres
  if (degree == 0)
118 134 storres
  {
119 134 storres
    initial_verbosity_level = pobyso_set_verbosity_off();
120 134 storres
    monomialSo = sollya_lib_copy_obj(coefficientSo);
121 134 storres
    pobyso_set_verbosity_to(initial_verbosity_level);
122 134 storres
  }
123 134 storres
  degreeSo    = sollya_lib_constant_from_int64(degree);
124 134 storres
  varToPowSo  = sollya_lib_build_function_pow(sollya_lib_free_variable(),
125 134 storres
                                              degreeSo);
126 134 storres
  /* Do not use the "build" version to avoid "eating up" the coefficient. */
127 134 storres
  monomialSo = sollya_lib_mul(coefficientSo,varToPowSo);
128 134 storres
  sollya_lib_clear_obj(varToPowSo);
129 134 storres
  /* Do not clear degreeSa: it was "eaten" by sollya-lib_build_function. */
130 134 storres
  return monomialSo;
131 133 storres
} /* End pobyso_new_monomial. */
132 133 storres
133 127 storres
/* @see pobyso.h#pobyso_parse_string*/
134 130 storres
pobyso_func_exp_t
135 26 storres
pobyso_parse_string(const char* expression)
136 26 storres
{
137 128 storres
  int expressionLength, i;
138 127 storres
  char *expressionWithSemiCo;
139 127 storres
  sollya_obj_t expressionSa;
140 128 storres
141 127 storres
  /* Arguments check. */
142 26 storres
  if (expression == NULL)
143 26 storres
  {
144 26 storres
    pobyso_error_message("pobyso_parse_string",
145 26 storres
                        "NULL_POINTER_ARGUMENT",
146 26 storres
                        "The expression is a NULL pointer");
147 134 storres
    return  NULL;
148 26 storres
  }
149 127 storres
  expressionLength = strlen(expression);
150 127 storres
  if (expressionLength == 0)
151 127 storres
  {
152 127 storres
    pobyso_error_message("pobyso_parse_string",
153 127 storres
                        "EMPTY_STRING_ARGUMENT",
154 127 storres
                        "The expression is an empty string");
155 134 storres
    return NULL;
156 127 storres
  }
157 128 storres
  /* Search from the last char of the expression until, whichever happens
158 128 storres
   * first:
159 128 storres
   * a ";" is found;
160 128 storres
   * a char  != ';' is found the the ";" is appended.
161 128 storres
   * If the head of the string is reached before any of these two events happens
162 128 storres
   * return an error.
163 128 storres
   */
164 128 storres
  for (i = expressionLength - 1 ; i >= 0 ; i--)
165 127 storres
  {
166 128 storres
    if (expression[i] == ';') /* Nothing special to do:
167 128 storres
                                 try to parse the string*/
168 127 storres
    {
169 128 storres
      expressionSa = sollya_lib_parse_string(expression);
170 132 storres
      return expressionSa;
171 127 storres
    }
172 128 storres
    else
173 128 storres
    {
174 128 storres
      if (expression[i] == ' ' || expression[i] == '\t') /* A blank,
175 128 storres
                                                           just continue. */
176 128 storres
      {
177 128 storres
        continue;
178 128 storres
      }
179 128 storres
      else /* a character != ';' and from a blank: create the ';'ed string. */
180 128 storres
      {
181 128 storres
        /* Create a new string for the expression, add the ";" and
182 128 storres
         * and call sollya_lib_parse_string. */
183 128 storres
        expressionWithSemiCo = calloc(i + 3, sizeof(char));
184 128 storres
        if (expressionWithSemiCo == NULL)
185 128 storres
        {
186 128 storres
          pobyso_error_message("pobyso_parse_string",
187 128 storres
                                "MEMORY_ALLOCATION_ERROR",
188 128 storres
                                "Could not allocate the expression string");
189 134 storres
          return NULL;
190 128 storres
        }
191 132 storres
        strncpy(expressionWithSemiCo, expression, i+1);
192 128 storres
        expressionWithSemiCo[i + 1] = ';';
193 128 storres
        expressionWithSemiCo[i + 2] = '\0';
194 128 storres
        expressionSa = sollya_lib_parse_string(expressionWithSemiCo);
195 128 storres
        free(expressionWithSemiCo);
196 132 storres
        return expressionSa;
197 128 storres
      } /* End character != ';' and from a blank. */
198 128 storres
    /* Create a new string for the expression, add the ";" and
199 128 storres
     * and call sollya_lib_parse_string. */
200 128 storres
    } /* End else. */
201 128 storres
  } /* End for. */
202 128 storres
  /* We get here, it is because we did not find any char == anything different
203 128 storres
   * from ' ' or '\t': the string is empty.
204 128 storres
   */
205 128 storres
  pobyso_error_message("pobyso_parse_string",
206 128 storres
                       "ONLY_BLANK_ARGUMENT",
207 128 storres
                        "The expression is only made of blanks");
208 134 storres
  return NULL;
209 128 storres
210 26 storres
} /* pobyso_parse_string */
211 26 storres
212 132 storres
pobyso_func_exp_t
213 132 storres
pobyso_remez_canonical_monomials_base(pobyso_func_exp_t function,
214 132 storres
                                      long int degree,
215 132 storres
                                      pobyso_range_t interval,
216 132 storres
                                      pobyso_func_exp_t weight,
217 132 storres
                                      double quality,
218 132 storres
                                      pobyso_range_t bounds)
219 132 storres
{
220 134 storres
  sollya_obj_t  degreeSo = NULL;
221 134 storres
  sollya_obj_t qualitySo = NULL;
222 132 storres
223 134 storres
  degreeSo = sollya_lib_constant_from_int(degree);
224 134 storres
  qualitySo = sollya_lib_constant_from_double(quality);
225 132 storres
226 134 storres
  sollya_lib_clear_obj(degreeSo);
227 134 storres
  sollya_lib_clear_obj(qualitySo);
228 132 storres
  return NULL;
229 132 storres
} /* End pobyso_remez_canonical_monomials_base. */
230 132 storres
231 132 storres
int
232 132 storres
pobyso_set_canonical_on()
233 132 storres
{
234 132 storres
  pobyso_on_off_t currentCanonicalModeSo;
235 132 storres
  pobyso_on_off_t on;
236 132 storres
237 132 storres
  currentCanonicalModeSo = sollya_lib_get_canonical();
238 132 storres
  if (sollya_lib_is_on(currentCanonicalModeSo))
239 132 storres
  {
240 134 storres
    sollya_lib_clear_obj(currentCanonicalModeSo);
241 134 storres
    return POBYSO_ON;
242 132 storres
  }
243 132 storres
  else
244 132 storres
  {
245 134 storres
    on = sollya_lib_on();
246 134 storres
    sollya_lib_set_canonical(on);
247 134 storres
    sollya_lib_clear_obj(on);
248 134 storres
    sollya_lib_clear_obj(currentCanonicalModeSo);
249 134 storres
    return POBYSO_OFF;
250 132 storres
  }
251 132 storres
} /* End pobyso_set_canonical_on. */
252 132 storres
253 134 storres
int
254 128 storres
pobyso_set_verbosity_off()
255 26 storres
{
256 134 storres
  sollya_obj_t verbosityLevelZeroSo;
257 134 storres
  sollya_obj_t currentVerbosityLevelSo = NULL;
258 134 storres
  int currentVerbosityLevel = 0;
259 128 storres
260 134 storres
  currentVerbosityLevelSo = sollya_lib_get_verbosity();
261 134 storres
  sollya_lib_get_constant_as_int(&currentVerbosityLevel,
262 134 storres
                                 currentVerbosityLevelSo);
263 134 storres
  verbosityLevelZeroSo = sollya_lib_constant_from_int(0);
264 134 storres
  sollya_lib_set_verbosity(verbosityLevelZeroSo);
265 134 storres
  sollya_lib_clear_obj(verbosityLevelZeroSo);
266 134 storres
  sollya_lib_clear_obj(currentVerbosityLevelSo);
267 134 storres
  return currentVerbosityLevel;
268 26 storres
} /* End of pobyso_set_verbosity_off. */
269 26 storres
270 134 storres
int
271 134 storres
pobyso_set_verbosity_to(int newVerbosityLevel)
272 26 storres
{
273 134 storres
  int initialVerbosityLevel = 0;
274 134 storres
  sollya_obj_t initialVerbosityLevelSo = NULL;
275 134 storres
  sollya_obj_t newVerbosityLevelSo = NULL;
276 134 storres
277 134 storres
  initialVerbosityLevelSo = sollya_lib_get_verbosity();
278 134 storres
  sollya_lib_get_constant_as_int(&initialVerbosityLevel,
279 134 storres
                                 initialVerbosityLevelSo);
280 134 storres
  sollya_lib_clear_obj(initialVerbosityLevelSo);
281 134 storres
  if (newVerbosityLevel < 0)
282 26 storres
  {
283 26 storres
    pobyso_error_message("pobyso_set_verbosity_to",
284 134 storres
                        "INVALID_VALUE",
285 134 storres
                        "The new verbosity level is a negative number");
286 134 storres
    return initialVerbosityLevel;
287 26 storres
  }
288 134 storres
  newVerbosityLevelSo = sollya_lib_constant_from_int(newVerbosityLevel);
289 134 storres
  sollya_lib_set_verbosity(newVerbosityLevelSo);
290 134 storres
  sollya_lib_clear_obj(newVerbosityLevelSo);
291 134 storres
  return initialVerbosityLevel;
292 26 storres
} /* End of pobyso_set_verbosity_to. */
293 26 storres
294 134 storres
/**
295 134 storres
 * @see pobyso.h#pobyso_subpoly
296 134 storres
 */
297 134 storres
pobyso_func_exp_t
298 134 storres
pobyso_subpoly(pobyso_func_exp_t polynomialSo, long expsNum,...)
299 132 storres
{
300 134 storres
  sollya_obj_t expsListSo = NULL;
301 134 storres
  sollya_obj_t* expsList  = NULL;
302 134 storres
  sollya_obj_t subpoly    = NULL;
303 134 storres
304 134 storres
  va_list vaExpsList;
305 134 storres
  int currentExp;
306 134 storres
  int i;
307 134 storres
308 134 storres
  /* Arguments check. */
309 134 storres
  if (polynomialSo == NULL) return NULL;
310 134 storres
  if (expsNum < 0) return NULL;
311 134 storres
  if (expsNum == 0) return sollya_lib_copy_obj(polynomialSo);
312 134 storres
313 134 storres
  va_start(vaExpsList, expsNum);
314 134 storres
  expsList = (sollya_obj_t*) malloc(expsNum * sizeof(sollya_obj_t));
315 134 storres
  if (expsList == NULL)
316 132 storres
  {
317 134 storres
    pobyso_error_message("pobyso_subpoly",
318 134 storres
                          "MEMORY_ALLOCATION_ERROR",
319 134 storres
                          "Could not allocate the expression string");
320 134 storres
    return NULL;
321 132 storres
  }
322 134 storres
  for (i = 0 ; i < expsNum ; i++)
323 134 storres
  {
324 134 storres
    currentExp = va_arg(vaExpsList, long);
325 134 storres
    expsList[i] = sollya_lib_constant_from_int64(currentExp);
326 134 storres
  } /* End for */
327 134 storres
  va_end(vaExpsList);
328 134 storres
  expsListSo = sollya_lib_list(expsList, expsNum);
329 134 storres
  if (expsList == NULL)
330 134 storres
  {
331 134 storres
    pobyso_error_message("pobyso_subpoly",
332 134 storres
                          "LIST_CREATIONERROR",
333 134 storres
                          "Could not create the exponents list");
334 134 storres
    for (i = 0 ; i < expsNum ; i++)
335 134 storres
    {
336 134 storres
      sollya_lib_clear_obj(expsList[i]);
337 134 storres
    }
338 134 storres
    free(expsList);
339 134 storres
    return NULL;
340 134 storres
  }
341 134 storres
  subpoly = sollya_lib_subpoly(polynomialSo, expsListSo);
342 134 storres
  sollya_lib_clear_obj(expsListSo);
343 134 storres
  for (i = 0 ; i < expsNum ; i++)
344 134 storres
  {
345 134 storres
    sollya_lib_clear_obj(expsList[i]);
346 134 storres
  }
347 134 storres
  free(expsList);
348 134 storres
  return subpoly;
349 134 storres
} /* pobyso_subpoly. */
350 132 storres
351 26 storres
/* Attic from the sollya_lib < 4. */
352 26 storres
#if 0
353 26 storres
chain*
354 26 storres
pobyso_create_canonical_monomials_base(const unsigned int degree)
355 26 storres
{
356 26 storres
  int i    = 0;
357 26 storres
  chain *monomials  = NULL;
358 26 storres
  node  *monomial   = NULL;
359 26 storres

360 26 storres
  for(i = degree ; i >= 0  ; i--)
361 26 storres
  {
362 26 storres
     monomial   = makePow(makeVariable(), makeConstantDouble((double)i));
363 26 storres
     monomials  = addElement(monomials, monomial);
364 26 storres
     fprintf(stderr, "pobyso_create_canonical_monomials_base: %u\n", i);
365 26 storres
  }
366 26 storres
  if (monomials == NULL)
367 26 storres
  {
368 26 storres
    pobyso_error_message("pobyso_create_canonical_monomial_base",
369 26 storres
                        "CHAIN_CREATION_ERROR",
370 26 storres
                        "Could not create the monomials chain");
371 26 storres
    return(NULL);
372 26 storres
  }
373 26 storres
  return(monomials);
374 26 storres
} /* End pobyso_create_canonical_monomials_base. */
375 26 storres

376 26 storres
chain*
377 26 storres
pobyso_create_chain_from_int_array(int* intArray,
378 26 storres
                                    const unsigned int arrayLength)
379 26 storres
{
380 26 storres
  int i = 0;
381 26 storres
  chain *newChain = NULL;
382 26 storres
  int *currentInt;
383 26 storres

384 26 storres
  if (arrayLength == 0) return(NULL);
385 26 storres
  if (intArray == NULL)
386 26 storres
  {
387 26 storres
    pobyso_error_message("pobyso_create_chain_from_int_array",
388 26 storres
                        "NULL_POINTER_ARGUMENT",
389 26 storres
                        "The array is a NULL pointer");
390 26 storres
    return(NULL);
391 26 storres
  }
392 26 storres
  for (i = arrayLength - 1 ; i >= 0 ; i--)
393 26 storres
  {
394 26 storres
    currentInt = malloc(sizeof(int));
395 26 storres
    if (currentInt == NULL)
396 26 storres
    {
397 26 storres
      pobyso_error_message("pobyso_create_chain_from_int_array",
398 26 storres
                          "MEMORY_ALLOCATION_ERROR",
399 26 storres
                          "Could not allocate one of the integers");
400 26 storres
      freeChain(newChain, free);
401 26 storres
      return(NULL);
402 26 storres
    }
403 26 storres
    *currentInt = intArray[i];
404 26 storres
    newChain = addElement(newChain, currentInt);
405 26 storres
  }
406 26 storres
  return(newChain);
407 26 storres
} // End pobyso_create_chain_from_int_array. */
408 26 storres

409 26 storres
chain*
410 26 storres
pobyso_create_chain_from_unsigned_int_array(unsigned int* intArray,
411 26 storres
                                        const unsigned int arrayLength)
412 26 storres
{
413 26 storres
  int i = 0;
414 26 storres
  chain *newChain = NULL;
415 26 storres
  unsigned int *currentInt;
416 26 storres

417 26 storres
  /* Argument checking. */
418 26 storres
  if (arrayLength == 0) return(NULL);
419 26 storres
  if (intArray == NULL)
420 26 storres
  {
421 26 storres
    pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
422 26 storres
                        "NULL_POINTER_ARGUMENT",
423 26 storres
                        "The array is a NULL pointer");
424 26 storres
    return(NULL);
425 26 storres
  }
426 26 storres
  for (i = arrayLength - 1 ; i >= 0 ; i--)
427 26 storres
  {
428 26 storres
    currentInt = malloc(sizeof(unsigned int));
429 26 storres
    if (currentInt == NULL)
430 26 storres
    {
431 26 storres
      pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
432 26 storres
                          "MEMORY_ALLOCATION_ERROR",
433 26 storres
                          "Could not allocate one of the integers");
434 26 storres
      freeChain(newChain, free);
435 26 storres
      return(NULL);
436 26 storres
    }
437 26 storres
    *currentInt = intArray[i];
438 26 storres
    newChain = addElement(newChain, currentInt);
439 26 storres
  }
440 26 storres
  return(newChain);
441 26 storres
} // End pobyso_create_chain_from_unsigned_int_array. */
442 26 storres

443 26 storres
node*
444 26 storres
pobyso_differentiate(node *functionNode)
445 26 storres
{
446 26 storres
  /* Argument checking. */
447 26 storres
  node *differentialNode;
448 26 storres
  if (functionNode == NULL)
449 26 storres
  {
450 26 storres
    pobyso_error_message("pobyso_differentiate",
451 26 storres
                        "NULL_POINTER_ARGUMENT",
452 26 storres
                        "The function to differentiate is a NULL pointer");
453 26 storres
    return(NULL);
454 26 storres
  }
455 26 storres
  differentialNode = differentiate(functionNode);
456 26 storres
  if (differentialNode == NULL)
457 26 storres
  {
458 26 storres
    pobyso_error_message("pobyso_differentiate",
459 26 storres
                        "INTERNAL ERROR",
460 26 storres
                        "Sollya could not differentiate the function");
461 26 storres
  }
462 26 storres
  return(differentialNode);
463 26 storres
} // End pobyso_differentiate
464 26 storres

465 26 storres

466 26 storres
int
467 26 storres
pobyso_dirty_infnorm(mpfr_t infNorm,
468 26 storres
                      node *functionNode,
469 26 storres
                      mpfr_t lowerBound,
470 26 storres
                      mpfr_t upperBound,
471 26 storres
                      mp_prec_t precision)
472 26 storres
{
473 26 storres
  int functionCallResult;
474 26 storres
  /* Arguments checking. */
475 26 storres
  if (functionNode == NULL)
476 26 storres
  {
477 26 storres
    pobyso_error_message("pobyso_dirty_infnorm",
478 26 storres
                        "NULL_POINTER_ARGUMENT",
479 26 storres
                        "The function to compute is a NULL pointer");
480 26 storres
    return(1);
481 26 storres
  }
482 26 storres
  if (mpfr_cmp(lowerBound, upperBound) > 0)
483 26 storres
  {
484 26 storres
    pobyso_error_message("pobyso_dirty_infnorm",
485 26 storres
                        "INCOHERENT_INPUT_DATA",
486 26 storres
                        "The lower bond is greater than the upper bound");
487 26 storres
    return(1);
488 26 storres
  }
489 26 storres
  /* Particular cases. */
490 26 storres
  if (mpfr_cmp(lowerBound, upperBound) == 0)
491 26 storres
  {
492 26 storres
    functionCallResult = pobyso_evaluate_faithful(infNorm,
493 26 storres
                                                  functionNode,
494 26 storres
                                                  lowerBound,
495 26 storres
                                                  precision);
496 26 storres
    return(functionCallResult);
497 26 storres
  }
498 26 storres
  if (isConstant(functionNode))
499 26 storres
  {
500 26 storres
    functionCallResult = pobyso_evaluate_faithful(infNorm,
501 26 storres
                                                  functionNode,
502 26 storres
                                                  lowerBound,
503 26 storres
                                                  precision);
504 26 storres
    if (!functionCallResult)
505 26 storres
    {
506 26 storres
      mpfr_abs(infNorm, infNorm, MPFR_RNDN);
507 26 storres
    }
508 26 storres
    return(functionCallResult);
509 26 storres
  }
510 26 storres
  uncertifiedInfnorm(infNorm,
511 26 storres
                      functionNode,
512 26 storres
                      lowerBound,
513 26 storres
                      upperBound,
514 26 storres
                      POBYSO_DEFAULT_POINTS,
515 26 storres
                      precision);
516 26 storres
  return(0);
517 26 storres
} /* End pobyso_dirty_infnorm. */
518 26 storres

519 26 storres
int
520 26 storres
pobyso_evaluate_faithful(mpfr_t faithfulEvaluation,
521 26 storres
                          node *nodeToEvaluate,
522 26 storres
                          mpfr_t argument,
523 26 storres
                          mpfr_prec_t precision)
524 26 storres
{
525 26 storres
  /* Check input arguments. */
526 26 storres
  if (nodeToEvaluate == NULL)
527 26 storres
  {
528 26 storres
    pobyso_error_message("pobyso_evaluate_faithful",
529 26 storres
                        "NULL_POINTER_ARGUMENT",
530 26 storres
                        "nodeToEvaluate is a NULL pointer");
531 26 storres
    return(1);
532 26 storres
  }
533 26 storres
  evaluateFaithful(faithfulEvaluation,
534 26 storres
                   nodeToEvaluate,
535 26 storres
                   argument,
536 26 storres
                   precision);
537 26 storres
  return(0);
538 26 storres
} /* End pobyso_evaluate_faithfull. */
539 26 storres

540 26 storres
chain*
541 26 storres
pobyso_find_zeros(node *function,
542 26 storres
                  mpfr_t *lower_bound,
543 26 storres
                  mpfr_t *upper_bound)
544 26 storres
{
545 26 storres
  mp_prec_t currentPrecision;
546 26 storres
  mpfr_t currentDiameter;
547 26 storres
  rangetype bounds;
548 26 storres

549 26 storres
  currentPrecision = getToolPrecision();
550 26 storres
  mpfr_init2(currentDiameter, currentPrecision);
551 26 storres

552 26 storres
  bounds.a = lower_bound;
553 26 storres
  bounds.b = upper_bound;
554 26 storres

555 26 storres
  if (bounds.a == NULL || bounds.b == NULL)
556 26 storres
  {
557 26 storres
    pobyso_error_message("pobyso_find_zeros",
558 26 storres
                        "MEMORY_ALLOCATION_ERROR",
559 26 storres
                        "Could not allocate one of the bounds");
560 26 storres
    return(NULL);
561 26 storres
  }
562 26 storres
  return(findZerosFunction(function,
563 26 storres
                            bounds,
564 26 storres
                            currentPrecision,
565 26 storres
                            currentDiameter));
566 26 storres
} /* End pobyso_find_zeros. */
567 26 storres

568 26 storres
void
569 26 storres
pobyso_free_chain_of_nodes(chain *theChainOfNodes)
570 26 storres
{
571 26 storres
  node *currentNode           = NULL;
572 26 storres
  chain *currentChainElement  = NULL;
573 26 storres
  chain *nextChainElement     = NULL;
574 26 storres

575 26 storres
  nextChainElement = theChainOfNodes;
576 26 storres

577 26 storres
  while(nextChainElement != NULL)
578 26 storres
  {
579 26 storres
    currentChainElement = nextChainElement;
580 26 storres
    currentNode = (node*)(currentChainElement->value);
581 26 storres
    nextChainElement = nextChainElement->next;
582 26 storres
    free_memory(currentNode);
583 26 storres
    free((void*)(currentChainElement));
584 26 storres
  }
585 26 storres
} /* End pobyso_free_chain_of_nodes. */
586 26 storres

587 26 storres
void
588 26 storres
pobyso_free_range(rangetype range)
589 26 storres
{
590 26 storres

591 26 storres
  mpfr_clear(*(range.a));
592 26 storres
  mpfr_clear(*(range.b));
593 26 storres
  free(range.a);
594 26 storres
  free(range.b);
595 26 storres
} /* End pobyso_free_range. */
596 26 storres

597 26 storres
node*
598 26 storres
pobyso_fp_minimax_canonical_monomials_base(node *function,
599 26 storres
                                      int degree,
600 26 storres
                                      chain *formats,
601 26 storres
                                      chain *points,
602 26 storres
                                      mpfr_t lowerBound,
603 26 storres
                                      mpfr_t upperBound,
604 26 storres
                                      int fpFixedArg,
605 26 storres
                                      int absRel,
606 26 storres
                                      node *constPart,
607 26 storres
                                      node *minimax)
608 26 storres
{
609 26 storres
  return(NULL);
610 26 storres
} /* End pobyso_fp_minimax_canonical_monomials_base. */
611 26 storres

612 26 storres
node*
613 26 storres
pobyso_parse_function(char *functionString,
614 26 storres
                      char *freeVariableNameString)
615 26 storres
{
616 26 storres
  if (functionString == NULL || freeVariableNameString == NULL)
617 26 storres
  {
618 26 storres
    pobyso_error_message("pobyso_parse_function",
619 26 storres
                        "NULL_POINTER_ARGUMENT",
620 26 storres
                        "One of the arguments is a NULL pointer");
621 26 storres
    return(NULL);
622 26 storres
  }
623 26 storres
  return(parseString(functionString));
624 26 storres

625 26 storres
} /* End pobyso_parse_function */
626 26 storres

627 26 storres
node*
628 26 storres
pobyso_remez_approx_canonical_monomials_base_for_error(node *functionNode,
629 26 storres
                                                  unsigned int mode,
630 26 storres
                                                  mpfr_t lowerBound,
631 26 storres
                                                  mpfr_t upperBound,
632 26 storres
                                                  mpfr_t eps)
633 26 storres
{
634 26 storres
  node *weight              = NULL;
635 26 storres
  node *bestApproxPolyNode  = NULL;
636 26 storres
  node *bestApproxHorner    = NULL;
637 26 storres
  node *errorNode           = NULL;
638 26 storres
  rangetype degreeRange;
639 26 storres
  mpfr_t quality;
640 26 storres
  mpfr_t currentError;
641 26 storres
  unsigned int degree;
642 26 storres

643 26 storres
  /* Check the parameters. */
644 26 storres
  if (functionNode == NULL)
645 26 storres
  {
646 26 storres
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
647 26 storres
                        "NULL_POINTER_ARGUMENT",
648 26 storres
                        "functionNode is a NULL pointer");
649 26 storres
    return(NULL);
650 26 storres
  }
651 26 storres
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
652 26 storres
  {
653 26 storres
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
654 26 storres
                        "INCOHERENT_INPUT_DATA",
655 26 storres
                        "the lower_bound >= upper_bound");
656 26 storres
    return(NULL);
657 26 storres
  }
658 26 storres
  /* Set the weight. */
659 26 storres
  if (mode == POBYSO_ABSOLUTE)
660 26 storres
  {
661 26 storres
    /* Set the weight to 1 for the ABSOLUTE_MODE. */
662 26 storres
    weight = makeConstantDouble(1.0);
663 26 storres
  }
664 26 storres
  else
665 26 storres
  {
666 26 storres
    if (mode == POBYSO_RELATIVE)
667 26 storres
    {
668 26 storres
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
669 26 storres
                          "NOT_IMPLEMENTED",
670 26 storres
                          "the search for relative error is not implemented yet");
671 26 storres
      return(NULL);
672 26 storres
    }
673 26 storres
    else
674 26 storres
    {
675 26 storres
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
676 26 storres
                          "INCOHERENT_INPUT_DATA",
677 26 storres
                          "the mode is node of POBYSO_ABOLUTE or POBYSO_RELATIVE");
678 26 storres
      return(NULL);
679 26 storres
    }
680 26 storres
  }
681 26 storres
  //fprintf(stderr, "\n\n\n******* I'm here! ********\n\n\n");
682 26 storres
  degreeRange = guessDegree(functionNode,
683 26 storres
                            weight,
684 26 storres
                            lowerBound,
685 26 storres
                            upperBound,
686 26 storres
                            eps,
687 26 storres
                            POBYSO_GUESS_DEGREE_BOUND);
688 26 storres
  degree = mpfr_get_ui(*(degreeRange.a), MPFR_RNDN);
689 26 storres
  //fprintf(stderr, "\n\n\n******* I'm back! ********\n\n\n");
690 26 storres
  fprintf(stderr, "Guessed degree: ");
691 26 storres
  mpfr_out_str(stderr, 10, 17, *(degreeRange.a), MPFR_RNDN);
692 26 storres
  fprintf(stderr, " - as int: %u\n", degree);
693 26 storres
  /* Reduce the degree by 1 in the foolish hope it could work. */
694 26 storres
  if (degree > 0) degree--;
695 26 storres
  /* Both elements of degreeRange where "inited" within guessDegree. */
696 26 storres
  mpfr_clear(*(degreeRange.a));
697 26 storres
  mpfr_clear(*(degreeRange.b));
698 26 storres
  free(degreeRange.a);
699 26 storres
  free(degreeRange.b);
700 26 storres
  /* Mimic the default behavior of interactive Sollya. */
701 26 storres
  mpfr_init(quality);
702 26 storres
  mpfr_set_d(quality, 1e-5, MPFR_RNDN);
703 26 storres
  mpfr_init2(currentError, getToolPrecision());
704 26 storres
  mpfr_set_inf(currentError,1);
705 26 storres

706 26 storres
  /* Try to refine the initial guess: loop with increasing degrees until
707 26 storres
   * we find a satisfactory one. */
708 26 storres
  while(mpfr_cmp(currentError, eps) > 0)
709 26 storres
  {
710 26 storres
    /* Get rid of the previous polynomial, if any. */
711 26 storres
    if (bestApproxPolyNode != NULL)
712 26 storres
    {
713 26 storres
      free_memory(bestApproxPolyNode);
714 26 storres
    }
715 26 storres
    fprintf(stderr, "Degree: %u\n", degree);
716 26 storres
    fprintf(stderr, "Calling pobyso_remez_canonical_monomials_base...\n");
717 26 storres
    /* Try to find a polynomial with the guessed degree. */
718 26 storres
    bestApproxPolyNode = pobyso_remez_canonical_monomials_base(functionNode,
719 26 storres
                                                            weight,
720 26 storres
                                                            degree,
721 26 storres
                                                            lowerBound,
722 26 storres
                                                            upperBound,
723 26 storres
                                                            quality);
724 26 storres

725 26 storres
    if (bestApproxPolyNode == NULL)
726 26 storres
    {
727 26 storres
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
728 26 storres
                          "INTERNAL_ERROR",
729 26 storres
                          "could not compute the bestApproxPolyNode");
730 26 storres
      mpfr_clear(currentError);
731 26 storres
      mpfr_clear(quality);
732 26 storres
      return(NULL);
733 26 storres
    }
734 26 storres

735 26 storres
    setDisplayMode(DISPLAY_MODE_DECIMAL);
736 26 storres
    fprintTree(stderr, bestApproxPolyNode);
737 26 storres
    fprintf(stderr, "\n\n");
738 26 storres

739 26 storres
    errorNode = makeSub(copyTree(functionNode), copyTree(bestApproxPolyNode));
740 26 storres
    /* Check the error with the computed polynomial. */
741 26 storres
    uncertifiedInfnorm(currentError,
742 26 storres
                        errorNode,
743 26 storres
                        lowerBound,
744 26 storres
                        upperBound,
745 26 storres
                        POBYSO_INF_NORM_NUM_POINTS,
746 26 storres
                        getToolPrecision());
747 26 storres
    fprintf(stderr, "Inf norm: ");
748 26 storres
    mpfr_out_str(stderr, 10, 17, currentError, MPFR_RNDN);
749 26 storres
    fprintf(stderr, "\n\n");
750 26 storres
    /* Free the errorNode but not the bestApproxPolyNode (we need it if
751 26 storres
     * we exit the loop at the next iteration). */
752 26 storres
    free_memory(errorNode);
753 26 storres
    degree++;
754 26 storres
  }
755 26 storres
  /* Use an intermediate variable, since horner() creates a new node
756 26 storres
   * and does not reorder the argument "in place". This allows for the memory
757 26 storres
   * reclaim of bestApproxHorner.
758 26 storres
   */
759 26 storres
  bestApproxHorner = horner(bestApproxPolyNode);
760 26 storres
  free_memory(bestApproxPolyNode);
761 26 storres
  mpfr_clear(currentError);
762 26 storres
  mpfr_clear(quality);
763 26 storres
  free_memory(weight);
764 26 storres
  return(bestApproxHorner);
765 26 storres
} /* End pobyso_remez_approx_canonical_monomials_base_for_error */
766 26 storres

767 26 storres
node*
768 26 storres
pobyso_remez_canonical_monomials_base(node *function,
769 26 storres
                                     node *weight,
770 26 storres
                                     unsigned int degree,
771 26 storres
                                     mpfr_t lowerBound,
772 26 storres
                                     mpfr_t upperBound,
773 26 storres
                                     mpfr_t quality)
774 26 storres
{
775 26 storres
  node  *bestApproxPoly = NULL;
776 26 storres
  chain *monomials      = NULL;
777 26 storres
  chain *curMonomial    = NULL;
778 26 storres

779 26 storres
  mpfr_t satisfying_error;
780 26 storres
  mpfr_t target_error;
781 26 storres

782 26 storres
  /* Argument checking */
783 26 storres
  /* Function tree. */
784 26 storres
  if (function == NULL)
785 26 storres
  {
786 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
787 26 storres
                        "NULL_POINTER_ARGUMENT",
788 26 storres
                        "the \"function\" argument is a NULL pointer");
789 26 storres
    return(NULL);
790 26 storres
  }
791 26 storres
  if (weight == NULL)
792 26 storres
  {
793 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
794 26 storres
                        "NULL_POINTER_ARGUMENT",
795 26 storres
                        "the \"weight\" argument is a NULL pointer");
796 26 storres
    return(NULL);
797 26 storres
  }
798 26 storres
  /* Check the bounds. */
799 26 storres
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
800 26 storres
  {
801 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
802 26 storres
                        "INCOHERENT_IMPUT_DATA",
803 26 storres
                        "the lower_bound >= upper_bound");
804 26 storres
    return(NULL);
805 26 storres
  }
806 26 storres
  /* The quality must be a non null positive number. */
807 26 storres
  if (mpfr_sgn(quality) <= 0)
808 26 storres
  {
809 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
810 26 storres
                        "INCOHERENT_INPUT_DATA",
811 26 storres
                        "the quality <= 0");
812 26 storres
  }
813 26 storres
  /* End argument checking. */
814 26 storres
  /* Create the monomials nodes chains. */
815 26 storres
  monomials = pobyso_create_canonical_monomials_base(degree);
816 26 storres
  fprintf(stderr, "monomials chain length = %d\n", lengthChain(monomials));
817 26 storres
  if (monomials == NULL || (lengthChain(monomials) != degree + 1))
818 26 storres
  {
819 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
820 26 storres
                        "CHAIN_CREATION_ERROR",
821 26 storres
                        "could not create the monomials chain");
822 26 storres
    return(NULL);
823 26 storres
  }
824 26 storres
  curMonomial = monomials;
825 26 storres

826 26 storres
  while (curMonomial != NULL)
827 26 storres
  {
828 26 storres
    fprintf(stderr, "monomial tree: ");
829 26 storres
    //mpfr_out_str(stderr, 10, 17, *((mpfr_t*)((node*)(curMonomial->value))->value), MPFR_RNDN);
830 26 storres
    fprintTree(stderr, (node*)(curMonomial->value));
831 26 storres
    fprintf(stderr, "\n");
832 26 storres
    curMonomial = curMonomial->next;
833 26 storres
  }
834 26 storres

835 26 storres
  /* Deal with NULL weight. */
836 26 storres
  if (weight == NULL)
837 26 storres
  {
838 26 storres
    weight = makeConstantDouble(1.0);
839 26 storres
  }
840 26 storres
  /* Compute the best polynomial with the required quality.
841 26 storres
     The behavior is as if satisfying error and target_error had
842 26 storres
     not been used.*/
843 26 storres
  mpfr_init(satisfying_error);
844 26 storres
  mpfr_init(target_error);
845 26 storres
  mpfr_set_str(satisfying_error, "0", 10, MPFR_RNDN);
846 26 storres
  mpfr_set_inf(target_error, 1);
847 26 storres

848 26 storres

849 26 storres
  fprintf(stderr, "satisfying_error: ");
850 26 storres
  mpfr_out_str(stderr, 10, 17, satisfying_error, MPFR_RNDN);
851 26 storres
  fprintf(stderr, ".\n");
852 26 storres
  fprintf(stderr, "target_error: ");
853 26 storres
  mpfr_out_str(stderr, 10, 17, target_error,MPFR_RNDN);
854 26 storres
  fprintf(stderr, ".\n");
855 26 storres

856 26 storres
  fprintf(stderr,
857 26 storres
          "current precision: %li\n", getToolPrecision());
858 26 storres
  /* Call the Sollya function. */
859 26 storres
  bestApproxPoly = remez(function,
860 26 storres
                          weight,
861 26 storres
                          monomials,
862 26 storres
                          lowerBound,
863 26 storres
                          upperBound,
864 26 storres
                          quality,
865 26 storres
                          satisfying_error,
866 26 storres
                          target_error,
867 26 storres
                          getToolPrecision());
868 26 storres

869 26 storres
  mpfr_clear(satisfying_error);
870 26 storres
  mpfr_clear(target_error);
871 26 storres
  pobyso_free_chain_of_nodes(monomials);
872 26 storres

873 26 storres
  return(bestApproxPoly);
874 26 storres
} /* End pobyso_remez_canonical_monomials_base. */
875 26 storres

876 26 storres
#endif
877 26 storres
878 26 storres
void
879 26 storres
pobyso_error_message(char *functionName, char *messageName, char* message)
880 26 storres
{
881 26 storres
  fprintf(stderr, "?%s: %s.\n%s.\n", functionName, messageName, message);
882 26 storres
} /* End pobyso_error_message */