Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (23,26 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 127 storres
/* @see pobyso.h#pobyso_autprint */
36 26 storres
void
37 26 storres
pobyso_autoprint(sollya_obj_t solObj, ...)
38 26 storres
{
39 26 storres
  va_list va;
40 26 storres
  va_start(va, solObj);
41 26 storres
  sollya_lib_v_autoprint(solObj, va);
42 26 storres
  va_end(va);
43 26 storres
} /* End pobyso_autoprint. */
44 26 storres
45 128 storres
46 127 storres
/* @see pobyso.h#pobyso_parse_string*/
47 130 storres
pobyso_func_exp_t
48 26 storres
pobyso_parse_string(const char* expression)
49 26 storres
{
50 128 storres
  int expressionLength, i;
51 127 storres
  char *expressionWithSemiCo;
52 127 storres
  sollya_obj_t expressionSa;
53 128 storres
54 127 storres
  /* Arguments check. */
55 26 storres
  if (expression == NULL)
56 26 storres
  {
57 26 storres
    pobyso_error_message("pobyso_parse_string",
58 26 storres
                        "NULL_POINTER_ARGUMENT",
59 26 storres
                        "The expression is a NULL pointer");
60 127 storres
    return(sollya_lib_error());
61 26 storres
  }
62 127 storres
  expressionLength = strlen(expression);
63 127 storres
  if (expressionLength == 0)
64 127 storres
  {
65 127 storres
    pobyso_error_message("pobyso_parse_string",
66 127 storres
                        "EMPTY_STRING_ARGUMENT",
67 127 storres
                        "The expression is an empty string");
68 132 storres
    return sollya_lib_error();
69 127 storres
  }
70 128 storres
  /* Search from the last char of the expression until, whichever happens
71 128 storres
   * first:
72 128 storres
   * a ";" is found;
73 128 storres
   * a char  != ';' is found the the ";" is appended.
74 128 storres
   * If the head of the string is reached before any of these two events happens
75 128 storres
   * return an error.
76 128 storres
   */
77 128 storres
  for (i = expressionLength - 1 ; i >= 0 ; i--)
78 127 storres
  {
79 128 storres
    if (expression[i] == ';') /* Nothing special to do:
80 128 storres
                                 try to parse the string*/
81 127 storres
    {
82 128 storres
      expressionSa = sollya_lib_parse_string(expression);
83 132 storres
      return expressionSa;
84 127 storres
    }
85 128 storres
    else
86 128 storres
    {
87 128 storres
      if (expression[i] == ' ' || expression[i] == '\t') /* A blank,
88 128 storres
                                                           just continue. */
89 128 storres
      {
90 128 storres
        continue;
91 128 storres
      }
92 128 storres
      else /* a character != ';' and from a blank: create the ';'ed string. */
93 128 storres
      {
94 128 storres
        /* Create a new string for the expression, add the ";" and
95 128 storres
         * and call sollya_lib_parse_string. */
96 128 storres
        expressionWithSemiCo = calloc(i + 3, sizeof(char));
97 128 storres
        if (expressionWithSemiCo == NULL)
98 128 storres
        {
99 128 storres
          pobyso_error_message("pobyso_parse_string",
100 128 storres
                                "MEMORY_ALLOCATION_ERROR",
101 128 storres
                                "Could not allocate the expression string");
102 132 storres
          return sollya_lib_error();
103 128 storres
        }
104 132 storres
        strncpy(expressionWithSemiCo, expression, i+1);
105 128 storres
        expressionWithSemiCo[i + 1] = ';';
106 128 storres
        expressionWithSemiCo[i + 2] = '\0';
107 128 storres
        expressionSa = sollya_lib_parse_string(expressionWithSemiCo);
108 128 storres
        free(expressionWithSemiCo);
109 132 storres
        return expressionSa;
110 128 storres
      } /* End character != ';' and from a blank. */
111 128 storres
    /* Create a new string for the expression, add the ";" and
112 128 storres
     * and call sollya_lib_parse_string. */
113 128 storres
    } /* End else. */
114 128 storres
  } /* End for. */
115 128 storres
  /* We get here, it is because we did not find any char == anything different
116 128 storres
   * from ' ' or '\t': the string is empty.
117 128 storres
   */
118 128 storres
  pobyso_error_message("pobyso_parse_string",
119 128 storres
                       "ONLY_BLANK_ARGUMENT",
120 128 storres
                        "The expression is only made of blanks");
121 128 storres
  return(sollya_lib_error());
122 128 storres
123 26 storres
} /* pobyso_parse_string */
124 26 storres
125 132 storres
pobyso_func_exp_t
126 132 storres
pobyso_remez_canonical_monomials_base(pobyso_func_exp_t function,
127 132 storres
                                      long int degree,
128 132 storres
                                      pobyso_range_t interval,
129 132 storres
                                      pobyso_func_exp_t weight,
130 132 storres
                                      double quality,
131 132 storres
                                      pobyso_range_t bounds)
132 132 storres
{
133 132 storres
  sollya_obj_t  degreeSa = NULL;
134 132 storres
  sollya_obj_t qualitySa = NULL;
135 132 storres
136 132 storres
  degreeSa = sollya_lib_constant_from_int(degree);
137 132 storres
  qualitySa = sollya_lib_constant_from_double(quality);
138 132 storres
139 132 storres
  return NULL;
140 132 storres
} /* End pobyso_remez_canonical_monomials_base. */
141 132 storres
142 132 storres
int
143 132 storres
pobyso_set_canonical_on()
144 132 storres
{
145 132 storres
  pobyso_on_off_t currentCanonicalModeSo;
146 132 storres
  int currentCanonicalMode;
147 132 storres
  pobyso_on_off_t on;
148 132 storres
149 132 storres
  on = sollya_lib_on();
150 132 storres
  currentCanonicalModeSo = sollya_lib_get_canonical();
151 132 storres
  if (sollya_lib_is_on(currentCanonicalModeSo))
152 132 storres
  {
153 132 storres
    currentCanonicalMode = POBYSO_ON;
154 132 storres
  }
155 132 storres
  else
156 132 storres
  {
157 132 storres
    currentCanonicalMode = POBYSO_OFF;
158 132 storres
  }
159 132 storres
  sollya_lib_set_canonical(on);
160 132 storres
  sollya_lib_clear_obj(on);
161 132 storres
  sollya_lib_clear_obj(currentCanonicalModeSo);
162 132 storres
  return currentCanonicalMode;
163 132 storres
} /* End pobyso_set_canonical_on. */
164 132 storres
165 132 storres
pobyso_sollya_verbosity_t
166 128 storres
pobyso_set_verbosity_off()
167 26 storres
{
168 26 storres
  sollya_obj_t verbosityLevelZero;
169 128 storres
  sollya_obj_t currentVerbosityLevel = NULL;
170 128 storres
171 128 storres
  currentVerbosityLevel = sollya_lib_get_verbosity();
172 26 storres
  verbosityLevelZero = sollya_lib_constant_from_int(0);
173 26 storres
  sollya_lib_set_verbosity(verbosityLevelZero);
174 26 storres
  sollya_lib_clear_obj(verbosityLevelZero);
175 128 storres
  return(currentVerbosityLevel);
176 26 storres
} /* End of pobyso_set_verbosity_off. */
177 26 storres
178 132 storres
pobyso_sollya_verbosity_t
179 132 storres
pobyso_set_verbosity_to(pobyso_sollya_verbosity_t newVerbosityLevel)
180 26 storres
{
181 131 storres
  sollya_obj_t currentVerbosityLevel = NULL;
182 26 storres
  if (newVerbosityLevel == NULL)
183 26 storres
  {
184 26 storres
    pobyso_error_message("pobyso_set_verbosity_to",
185 26 storres
                        "NULL_POINTER_ARGUMENT",
186 132 storres
                        "The new verbosity level is a null pointer");
187 128 storres
    return(sollya_lib_error());
188 26 storres
  }
189 131 storres
  currentVerbosityLevel = sollya_lib_get_verbosity();
190 26 storres
  sollya_lib_set_verbosity(newVerbosityLevel);
191 131 storres
  return(currentVerbosityLevel);
192 26 storres
} /* End of pobyso_set_verbosity_to. */
193 26 storres
194 132 storres
pobyso_sollya_verbosity_t
195 132 storres
pobyso_set_verbosity_to_int(int intVerbosityLevel)
196 132 storres
{
197 132 storres
  sollya_obj_t currentVerbosityLevel = NULL;
198 132 storres
  sollya_obj_t newVerbosityLevel     = NULL;
199 132 storres
  if (intVerbosityLevel < 0)
200 132 storres
  {
201 132 storres
    pobyso_error_message("pobyso_set_verbosity_to",
202 132 storres
                        "INVALID_VALUE",
203 132 storres
                        "The new verbosity level is a negative number");
204 132 storres
    return(sollya_lib_error());
205 132 storres
  }
206 132 storres
  newVerbosityLevel = sollya_lib_constant_from_int(intVerbosityLevel);
207 132 storres
  currentVerbosityLevel = sollya_lib_get_verbosity();
208 132 storres
  sollya_lib_set_verbosity(newVerbosityLevel);
209 132 storres
  return(currentVerbosityLevel);
210 132 storres
} /* End of pobyso_set_verbosity_to_int. */
211 132 storres
212 26 storres
/* Attic from the sollya_lib < 4. */
213 26 storres
#if 0
214 26 storres
chain*
215 26 storres
pobyso_create_canonical_monomials_base(const unsigned int degree)
216 26 storres
{
217 26 storres
  int i    = 0;
218 26 storres
  chain *monomials  = NULL;
219 26 storres
  node  *monomial   = NULL;
220 26 storres

221 26 storres
  for(i = degree ; i >= 0  ; i--)
222 26 storres
  {
223 26 storres
     monomial   = makePow(makeVariable(), makeConstantDouble((double)i));
224 26 storres
     monomials  = addElement(monomials, monomial);
225 26 storres
     fprintf(stderr, "pobyso_create_canonical_monomials_base: %u\n", i);
226 26 storres
  }
227 26 storres
  if (monomials == NULL)
228 26 storres
  {
229 26 storres
    pobyso_error_message("pobyso_create_canonical_monomial_base",
230 26 storres
                        "CHAIN_CREATION_ERROR",
231 26 storres
                        "Could not create the monomials chain");
232 26 storres
    return(NULL);
233 26 storres
  }
234 26 storres
  return(monomials);
235 26 storres
} /* End pobyso_create_canonical_monomials_base. */
236 26 storres

237 26 storres
chain*
238 26 storres
pobyso_create_chain_from_int_array(int* intArray,
239 26 storres
                                    const unsigned int arrayLength)
240 26 storres
{
241 26 storres
  int i = 0;
242 26 storres
  chain *newChain = NULL;
243 26 storres
  int *currentInt;
244 26 storres

245 26 storres
  if (arrayLength == 0) return(NULL);
246 26 storres
  if (intArray == NULL)
247 26 storres
  {
248 26 storres
    pobyso_error_message("pobyso_create_chain_from_int_array",
249 26 storres
                        "NULL_POINTER_ARGUMENT",
250 26 storres
                        "The array is a NULL pointer");
251 26 storres
    return(NULL);
252 26 storres
  }
253 26 storres
  for (i = arrayLength - 1 ; i >= 0 ; i--)
254 26 storres
  {
255 26 storres
    currentInt = malloc(sizeof(int));
256 26 storres
    if (currentInt == NULL)
257 26 storres
    {
258 26 storres
      pobyso_error_message("pobyso_create_chain_from_int_array",
259 26 storres
                          "MEMORY_ALLOCATION_ERROR",
260 26 storres
                          "Could not allocate one of the integers");
261 26 storres
      freeChain(newChain, free);
262 26 storres
      return(NULL);
263 26 storres
    }
264 26 storres
    *currentInt = intArray[i];
265 26 storres
    newChain = addElement(newChain, currentInt);
266 26 storres
  }
267 26 storres
  return(newChain);
268 26 storres
} // End pobyso_create_chain_from_int_array. */
269 26 storres

270 26 storres
chain*
271 26 storres
pobyso_create_chain_from_unsigned_int_array(unsigned int* intArray,
272 26 storres
                                        const unsigned int arrayLength)
273 26 storres
{
274 26 storres
  int i = 0;
275 26 storres
  chain *newChain = NULL;
276 26 storres
  unsigned int *currentInt;
277 26 storres

278 26 storres
  /* Argument checking. */
279 26 storres
  if (arrayLength == 0) return(NULL);
280 26 storres
  if (intArray == NULL)
281 26 storres
  {
282 26 storres
    pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
283 26 storres
                        "NULL_POINTER_ARGUMENT",
284 26 storres
                        "The array is a NULL pointer");
285 26 storres
    return(NULL);
286 26 storres
  }
287 26 storres
  for (i = arrayLength - 1 ; i >= 0 ; i--)
288 26 storres
  {
289 26 storres
    currentInt = malloc(sizeof(unsigned int));
290 26 storres
    if (currentInt == NULL)
291 26 storres
    {
292 26 storres
      pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
293 26 storres
                          "MEMORY_ALLOCATION_ERROR",
294 26 storres
                          "Could not allocate one of the integers");
295 26 storres
      freeChain(newChain, free);
296 26 storres
      return(NULL);
297 26 storres
    }
298 26 storres
    *currentInt = intArray[i];
299 26 storres
    newChain = addElement(newChain, currentInt);
300 26 storres
  }
301 26 storres
  return(newChain);
302 26 storres
} // End pobyso_create_chain_from_unsigned_int_array. */
303 26 storres

304 26 storres
node*
305 26 storres
pobyso_differentiate(node *functionNode)
306 26 storres
{
307 26 storres
  /* Argument checking. */
308 26 storres
  node *differentialNode;
309 26 storres
  if (functionNode == NULL)
310 26 storres
  {
311 26 storres
    pobyso_error_message("pobyso_differentiate",
312 26 storres
                        "NULL_POINTER_ARGUMENT",
313 26 storres
                        "The function to differentiate is a NULL pointer");
314 26 storres
    return(NULL);
315 26 storres
  }
316 26 storres
  differentialNode = differentiate(functionNode);
317 26 storres
  if (differentialNode == NULL)
318 26 storres
  {
319 26 storres
    pobyso_error_message("pobyso_differentiate",
320 26 storres
                        "INTERNAL ERROR",
321 26 storres
                        "Sollya could not differentiate the function");
322 26 storres
  }
323 26 storres
  return(differentialNode);
324 26 storres
} // End pobyso_differentiate
325 26 storres

326 26 storres

327 26 storres
int
328 26 storres
pobyso_dirty_infnorm(mpfr_t infNorm,
329 26 storres
                      node *functionNode,
330 26 storres
                      mpfr_t lowerBound,
331 26 storres
                      mpfr_t upperBound,
332 26 storres
                      mp_prec_t precision)
333 26 storres
{
334 26 storres
  int functionCallResult;
335 26 storres
  /* Arguments checking. */
336 26 storres
  if (functionNode == NULL)
337 26 storres
  {
338 26 storres
    pobyso_error_message("pobyso_dirty_infnorm",
339 26 storres
                        "NULL_POINTER_ARGUMENT",
340 26 storres
                        "The function to compute is a NULL pointer");
341 26 storres
    return(1);
342 26 storres
  }
343 26 storres
  if (mpfr_cmp(lowerBound, upperBound) > 0)
344 26 storres
  {
345 26 storres
    pobyso_error_message("pobyso_dirty_infnorm",
346 26 storres
                        "INCOHERENT_INPUT_DATA",
347 26 storres
                        "The lower bond is greater than the upper bound");
348 26 storres
    return(1);
349 26 storres
  }
350 26 storres
  /* Particular cases. */
351 26 storres
  if (mpfr_cmp(lowerBound, upperBound) == 0)
352 26 storres
  {
353 26 storres
    functionCallResult = pobyso_evaluate_faithful(infNorm,
354 26 storres
                                                  functionNode,
355 26 storres
                                                  lowerBound,
356 26 storres
                                                  precision);
357 26 storres
    return(functionCallResult);
358 26 storres
  }
359 26 storres
  if (isConstant(functionNode))
360 26 storres
  {
361 26 storres
    functionCallResult = pobyso_evaluate_faithful(infNorm,
362 26 storres
                                                  functionNode,
363 26 storres
                                                  lowerBound,
364 26 storres
                                                  precision);
365 26 storres
    if (!functionCallResult)
366 26 storres
    {
367 26 storres
      mpfr_abs(infNorm, infNorm, MPFR_RNDN);
368 26 storres
    }
369 26 storres
    return(functionCallResult);
370 26 storres
  }
371 26 storres
  uncertifiedInfnorm(infNorm,
372 26 storres
                      functionNode,
373 26 storres
                      lowerBound,
374 26 storres
                      upperBound,
375 26 storres
                      POBYSO_DEFAULT_POINTS,
376 26 storres
                      precision);
377 26 storres
  return(0);
378 26 storres
} /* End pobyso_dirty_infnorm. */
379 26 storres

380 26 storres
int
381 26 storres
pobyso_evaluate_faithful(mpfr_t faithfulEvaluation,
382 26 storres
                          node *nodeToEvaluate,
383 26 storres
                          mpfr_t argument,
384 26 storres
                          mpfr_prec_t precision)
385 26 storres
{
386 26 storres
  /* Check input arguments. */
387 26 storres
  if (nodeToEvaluate == NULL)
388 26 storres
  {
389 26 storres
    pobyso_error_message("pobyso_evaluate_faithful",
390 26 storres
                        "NULL_POINTER_ARGUMENT",
391 26 storres
                        "nodeToEvaluate is a NULL pointer");
392 26 storres
    return(1);
393 26 storres
  }
394 26 storres
  evaluateFaithful(faithfulEvaluation,
395 26 storres
                   nodeToEvaluate,
396 26 storres
                   argument,
397 26 storres
                   precision);
398 26 storres
  return(0);
399 26 storres
} /* End pobyso_evaluate_faithfull. */
400 26 storres

401 26 storres
chain*
402 26 storres
pobyso_find_zeros(node *function,
403 26 storres
                  mpfr_t *lower_bound,
404 26 storres
                  mpfr_t *upper_bound)
405 26 storres
{
406 26 storres
  mp_prec_t currentPrecision;
407 26 storres
  mpfr_t currentDiameter;
408 26 storres
  rangetype bounds;
409 26 storres

410 26 storres
  currentPrecision = getToolPrecision();
411 26 storres
  mpfr_init2(currentDiameter, currentPrecision);
412 26 storres

413 26 storres
  bounds.a = lower_bound;
414 26 storres
  bounds.b = upper_bound;
415 26 storres

416 26 storres
  if (bounds.a == NULL || bounds.b == NULL)
417 26 storres
  {
418 26 storres
    pobyso_error_message("pobyso_find_zeros",
419 26 storres
                        "MEMORY_ALLOCATION_ERROR",
420 26 storres
                        "Could not allocate one of the bounds");
421 26 storres
    return(NULL);
422 26 storres
  }
423 26 storres
  return(findZerosFunction(function,
424 26 storres
                            bounds,
425 26 storres
                            currentPrecision,
426 26 storres
                            currentDiameter));
427 26 storres
} /* End pobyso_find_zeros. */
428 26 storres

429 26 storres
void
430 26 storres
pobyso_free_chain_of_nodes(chain *theChainOfNodes)
431 26 storres
{
432 26 storres
  node *currentNode           = NULL;
433 26 storres
  chain *currentChainElement  = NULL;
434 26 storres
  chain *nextChainElement     = NULL;
435 26 storres

436 26 storres
  nextChainElement = theChainOfNodes;
437 26 storres

438 26 storres
  while(nextChainElement != NULL)
439 26 storres
  {
440 26 storres
    currentChainElement = nextChainElement;
441 26 storres
    currentNode = (node*)(currentChainElement->value);
442 26 storres
    nextChainElement = nextChainElement->next;
443 26 storres
    free_memory(currentNode);
444 26 storres
    free((void*)(currentChainElement));
445 26 storres
  }
446 26 storres
} /* End pobyso_free_chain_of_nodes. */
447 26 storres

448 26 storres
void
449 26 storres
pobyso_free_range(rangetype range)
450 26 storres
{
451 26 storres

452 26 storres
  mpfr_clear(*(range.a));
453 26 storres
  mpfr_clear(*(range.b));
454 26 storres
  free(range.a);
455 26 storres
  free(range.b);
456 26 storres
} /* End pobyso_free_range. */
457 26 storres

458 26 storres
node*
459 26 storres
pobyso_fp_minimax_canonical_monomials_base(node *function,
460 26 storres
                                      int degree,
461 26 storres
                                      chain *formats,
462 26 storres
                                      chain *points,
463 26 storres
                                      mpfr_t lowerBound,
464 26 storres
                                      mpfr_t upperBound,
465 26 storres
                                      int fpFixedArg,
466 26 storres
                                      int absRel,
467 26 storres
                                      node *constPart,
468 26 storres
                                      node *minimax)
469 26 storres
{
470 26 storres
  return(NULL);
471 26 storres
} /* End pobyso_fp_minimax_canonical_monomials_base. */
472 26 storres

473 26 storres
node*
474 26 storres
pobyso_parse_function(char *functionString,
475 26 storres
                      char *freeVariableNameString)
476 26 storres
{
477 26 storres
  if (functionString == NULL || freeVariableNameString == NULL)
478 26 storres
  {
479 26 storres
    pobyso_error_message("pobyso_parse_function",
480 26 storres
                        "NULL_POINTER_ARGUMENT",
481 26 storres
                        "One of the arguments is a NULL pointer");
482 26 storres
    return(NULL);
483 26 storres
  }
484 26 storres
  return(parseString(functionString));
485 26 storres

486 26 storres
} /* End pobyso_parse_function */
487 26 storres

488 26 storres
node*
489 26 storres
pobyso_remez_approx_canonical_monomials_base_for_error(node *functionNode,
490 26 storres
                                                  unsigned int mode,
491 26 storres
                                                  mpfr_t lowerBound,
492 26 storres
                                                  mpfr_t upperBound,
493 26 storres
                                                  mpfr_t eps)
494 26 storres
{
495 26 storres
  node *weight              = NULL;
496 26 storres
  node *bestApproxPolyNode  = NULL;
497 26 storres
  node *bestApproxHorner    = NULL;
498 26 storres
  node *errorNode           = NULL;
499 26 storres
  rangetype degreeRange;
500 26 storres
  mpfr_t quality;
501 26 storres
  mpfr_t currentError;
502 26 storres
  unsigned int degree;
503 26 storres

504 26 storres
  /* Check the parameters. */
505 26 storres
  if (functionNode == NULL)
506 26 storres
  {
507 26 storres
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
508 26 storres
                        "NULL_POINTER_ARGUMENT",
509 26 storres
                        "functionNode is a NULL pointer");
510 26 storres
    return(NULL);
511 26 storres
  }
512 26 storres
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
513 26 storres
  {
514 26 storres
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
515 26 storres
                        "INCOHERENT_INPUT_DATA",
516 26 storres
                        "the lower_bound >= upper_bound");
517 26 storres
    return(NULL);
518 26 storres
  }
519 26 storres
  /* Set the weight. */
520 26 storres
  if (mode == POBYSO_ABSOLUTE)
521 26 storres
  {
522 26 storres
    /* Set the weight to 1 for the ABSOLUTE_MODE. */
523 26 storres
    weight = makeConstantDouble(1.0);
524 26 storres
  }
525 26 storres
  else
526 26 storres
  {
527 26 storres
    if (mode == POBYSO_RELATIVE)
528 26 storres
    {
529 26 storres
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
530 26 storres
                          "NOT_IMPLEMENTED",
531 26 storres
                          "the search for relative error is not implemented yet");
532 26 storres
      return(NULL);
533 26 storres
    }
534 26 storres
    else
535 26 storres
    {
536 26 storres
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
537 26 storres
                          "INCOHERENT_INPUT_DATA",
538 26 storres
                          "the mode is node of POBYSO_ABOLUTE or POBYSO_RELATIVE");
539 26 storres
      return(NULL);
540 26 storres
    }
541 26 storres
  }
542 26 storres
  //fprintf(stderr, "\n\n\n******* I'm here! ********\n\n\n");
543 26 storres
  degreeRange = guessDegree(functionNode,
544 26 storres
                            weight,
545 26 storres
                            lowerBound,
546 26 storres
                            upperBound,
547 26 storres
                            eps,
548 26 storres
                            POBYSO_GUESS_DEGREE_BOUND);
549 26 storres
  degree = mpfr_get_ui(*(degreeRange.a), MPFR_RNDN);
550 26 storres
  //fprintf(stderr, "\n\n\n******* I'm back! ********\n\n\n");
551 26 storres
  fprintf(stderr, "Guessed degree: ");
552 26 storres
  mpfr_out_str(stderr, 10, 17, *(degreeRange.a), MPFR_RNDN);
553 26 storres
  fprintf(stderr, " - as int: %u\n", degree);
554 26 storres
  /* Reduce the degree by 1 in the foolish hope it could work. */
555 26 storres
  if (degree > 0) degree--;
556 26 storres
  /* Both elements of degreeRange where "inited" within guessDegree. */
557 26 storres
  mpfr_clear(*(degreeRange.a));
558 26 storres
  mpfr_clear(*(degreeRange.b));
559 26 storres
  free(degreeRange.a);
560 26 storres
  free(degreeRange.b);
561 26 storres
  /* Mimic the default behavior of interactive Sollya. */
562 26 storres
  mpfr_init(quality);
563 26 storres
  mpfr_set_d(quality, 1e-5, MPFR_RNDN);
564 26 storres
  mpfr_init2(currentError, getToolPrecision());
565 26 storres
  mpfr_set_inf(currentError,1);
566 26 storres

567 26 storres
  /* Try to refine the initial guess: loop with increasing degrees until
568 26 storres
   * we find a satisfactory one. */
569 26 storres
  while(mpfr_cmp(currentError, eps) > 0)
570 26 storres
  {
571 26 storres
    /* Get rid of the previous polynomial, if any. */
572 26 storres
    if (bestApproxPolyNode != NULL)
573 26 storres
    {
574 26 storres
      free_memory(bestApproxPolyNode);
575 26 storres
    }
576 26 storres
    fprintf(stderr, "Degree: %u\n", degree);
577 26 storres
    fprintf(stderr, "Calling pobyso_remez_canonical_monomials_base...\n");
578 26 storres
    /* Try to find a polynomial with the guessed degree. */
579 26 storres
    bestApproxPolyNode = pobyso_remez_canonical_monomials_base(functionNode,
580 26 storres
                                                            weight,
581 26 storres
                                                            degree,
582 26 storres
                                                            lowerBound,
583 26 storres
                                                            upperBound,
584 26 storres
                                                            quality);
585 26 storres

586 26 storres
    if (bestApproxPolyNode == NULL)
587 26 storres
    {
588 26 storres
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
589 26 storres
                          "INTERNAL_ERROR",
590 26 storres
                          "could not compute the bestApproxPolyNode");
591 26 storres
      mpfr_clear(currentError);
592 26 storres
      mpfr_clear(quality);
593 26 storres
      return(NULL);
594 26 storres
    }
595 26 storres

596 26 storres
    setDisplayMode(DISPLAY_MODE_DECIMAL);
597 26 storres
    fprintTree(stderr, bestApproxPolyNode);
598 26 storres
    fprintf(stderr, "\n\n");
599 26 storres

600 26 storres
    errorNode = makeSub(copyTree(functionNode), copyTree(bestApproxPolyNode));
601 26 storres
    /* Check the error with the computed polynomial. */
602 26 storres
    uncertifiedInfnorm(currentError,
603 26 storres
                        errorNode,
604 26 storres
                        lowerBound,
605 26 storres
                        upperBound,
606 26 storres
                        POBYSO_INF_NORM_NUM_POINTS,
607 26 storres
                        getToolPrecision());
608 26 storres
    fprintf(stderr, "Inf norm: ");
609 26 storres
    mpfr_out_str(stderr, 10, 17, currentError, MPFR_RNDN);
610 26 storres
    fprintf(stderr, "\n\n");
611 26 storres
    /* Free the errorNode but not the bestApproxPolyNode (we need it if
612 26 storres
     * we exit the loop at the next iteration). */
613 26 storres
    free_memory(errorNode);
614 26 storres
    degree++;
615 26 storres
  }
616 26 storres
  /* Use an intermediate variable, since horner() creates a new node
617 26 storres
   * and does not reorder the argument "in place". This allows for the memory
618 26 storres
   * reclaim of bestApproxHorner.
619 26 storres
   */
620 26 storres
  bestApproxHorner = horner(bestApproxPolyNode);
621 26 storres
  free_memory(bestApproxPolyNode);
622 26 storres
  mpfr_clear(currentError);
623 26 storres
  mpfr_clear(quality);
624 26 storres
  free_memory(weight);
625 26 storres
  return(bestApproxHorner);
626 26 storres
} /* End pobyso_remez_approx_canonical_monomials_base_for_error */
627 26 storres

628 26 storres
node*
629 26 storres
pobyso_remez_canonical_monomials_base(node *function,
630 26 storres
                                     node *weight,
631 26 storres
                                     unsigned int degree,
632 26 storres
                                     mpfr_t lowerBound,
633 26 storres
                                     mpfr_t upperBound,
634 26 storres
                                     mpfr_t quality)
635 26 storres
{
636 26 storres
  node  *bestApproxPoly = NULL;
637 26 storres
  chain *monomials      = NULL;
638 26 storres
  chain *curMonomial    = NULL;
639 26 storres

640 26 storres
  mpfr_t satisfying_error;
641 26 storres
  mpfr_t target_error;
642 26 storres

643 26 storres
  /* Argument checking */
644 26 storres
  /* Function tree. */
645 26 storres
  if (function == NULL)
646 26 storres
  {
647 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
648 26 storres
                        "NULL_POINTER_ARGUMENT",
649 26 storres
                        "the \"function\" argument is a NULL pointer");
650 26 storres
    return(NULL);
651 26 storres
  }
652 26 storres
  if (weight == NULL)
653 26 storres
  {
654 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
655 26 storres
                        "NULL_POINTER_ARGUMENT",
656 26 storres
                        "the \"weight\" argument is a NULL pointer");
657 26 storres
    return(NULL);
658 26 storres
  }
659 26 storres
  /* Check the bounds. */
660 26 storres
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
661 26 storres
  {
662 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
663 26 storres
                        "INCOHERENT_IMPUT_DATA",
664 26 storres
                        "the lower_bound >= upper_bound");
665 26 storres
    return(NULL);
666 26 storres
  }
667 26 storres
  /* The quality must be a non null positive number. */
668 26 storres
  if (mpfr_sgn(quality) <= 0)
669 26 storres
  {
670 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
671 26 storres
                        "INCOHERENT_INPUT_DATA",
672 26 storres
                        "the quality <= 0");
673 26 storres
  }
674 26 storres
  /* End argument checking. */
675 26 storres
  /* Create the monomials nodes chains. */
676 26 storres
  monomials = pobyso_create_canonical_monomials_base(degree);
677 26 storres
  fprintf(stderr, "monomials chain length = %d\n", lengthChain(monomials));
678 26 storres
  if (monomials == NULL || (lengthChain(monomials) != degree + 1))
679 26 storres
  {
680 26 storres
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
681 26 storres
                        "CHAIN_CREATION_ERROR",
682 26 storres
                        "could not create the monomials chain");
683 26 storres
    return(NULL);
684 26 storres
  }
685 26 storres
  curMonomial = monomials;
686 26 storres

687 26 storres
  while (curMonomial != NULL)
688 26 storres
  {
689 26 storres
    fprintf(stderr, "monomial tree: ");
690 26 storres
    //mpfr_out_str(stderr, 10, 17, *((mpfr_t*)((node*)(curMonomial->value))->value), MPFR_RNDN);
691 26 storres
    fprintTree(stderr, (node*)(curMonomial->value));
692 26 storres
    fprintf(stderr, "\n");
693 26 storres
    curMonomial = curMonomial->next;
694 26 storres
  }
695 26 storres

696 26 storres
  /* Deal with NULL weight. */
697 26 storres
  if (weight == NULL)
698 26 storres
  {
699 26 storres
    weight = makeConstantDouble(1.0);
700 26 storres
  }
701 26 storres
  /* Compute the best polynomial with the required quality.
702 26 storres
     The behavior is as if satisfying error and target_error had
703 26 storres
     not been used.*/
704 26 storres
  mpfr_init(satisfying_error);
705 26 storres
  mpfr_init(target_error);
706 26 storres
  mpfr_set_str(satisfying_error, "0", 10, MPFR_RNDN);
707 26 storres
  mpfr_set_inf(target_error, 1);
708 26 storres

709 26 storres

710 26 storres
  fprintf(stderr, "satisfying_error: ");
711 26 storres
  mpfr_out_str(stderr, 10, 17, satisfying_error, MPFR_RNDN);
712 26 storres
  fprintf(stderr, ".\n");
713 26 storres
  fprintf(stderr, "target_error: ");
714 26 storres
  mpfr_out_str(stderr, 10, 17, target_error,MPFR_RNDN);
715 26 storres
  fprintf(stderr, ".\n");
716 26 storres

717 26 storres
  fprintf(stderr,
718 26 storres
          "current precision: %li\n", getToolPrecision());
719 26 storres
  /* Call the Sollya function. */
720 26 storres
  bestApproxPoly = remez(function,
721 26 storres
                          weight,
722 26 storres
                          monomials,
723 26 storres
                          lowerBound,
724 26 storres
                          upperBound,
725 26 storres
                          quality,
726 26 storres
                          satisfying_error,
727 26 storres
                          target_error,
728 26 storres
                          getToolPrecision());
729 26 storres

730 26 storres
  mpfr_clear(satisfying_error);
731 26 storres
  mpfr_clear(target_error);
732 26 storres
  pobyso_free_chain_of_nodes(monomials);
733 26 storres

734 26 storres
  return(bestApproxPoly);
735 26 storres
} /* End pobyso_remez_canonical_monomials_base. */
736 26 storres

737 26 storres
#endif
738 26 storres
739 26 storres
void
740 26 storres
pobyso_error_message(char *functionName, char *messageName, char* message)
741 26 storres
{
742 26 storres
  fprintf(stderr, "?%s: %s.\n%s.\n", functionName, messageName, message);
743 26 storres
} /* End pobyso_error_message */