Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (24,57 ko)

1
/** @file pobyso.c
2
 * Name & purpose
3
 *
4
 * @author S.T.
5
 * @date 2011-10-12
6
 *
7
 *
8
 */
9

    
10
/******************************************************************************/
11
/* Headers, applying the "particular to general" convention.*/
12

    
13
#include "pobyso.h"
14

    
15
/* includes of local headers */
16

    
17
/* includes of project headers */
18

    
19
/* includes of system headers */
20
#include <string.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23

    
24
/* Other declarations */
25

    
26
/* Internal prototypes */
27
void
28
pobyso_error_message(char *functionName, char *messageName, char* message);
29
/* Types, constants and macros definitions */
30

    
31
/* Global variables */
32

    
33
/* Functions */
34

    
35
/* @see pobyso.h#pobyso_autprint */
36
void
37
pobyso_autoprint(sollya_obj_t solObj, ...)
38
{
39
  va_list va;
40
  va_start(va, solObj);
41
  sollya_lib_v_autoprint(solObj, va);
42
  va_end(va);
43
} /* End pobyso_autoprint. */
44

    
45
/* @see pobyso.h#pobyso_parse*/
46
pobyso_func_exp_t
47
pobyso_parse(const char* expression)
48
{
49
  int expressionLength, i;
50
  char *expressionWithSemiCo;
51
  sollya_obj_t expressionStringSa;
52
  sollya_obj_t expressionSa;
53

    
54
  /* Arguments check. */
55
  if (expression == NULL)
56
  {
57
    pobyso_error_message("pobyso_parse",
58
                        "NULL_POINTER_ARGUMENT",
59
                        "The expression is a NULL pointer");
60
    return(sollya_lib_error());
61
  }
62
  expressionLength = strlen(expression);
63
  if (expressionLength == 0)
64
  {
65
    pobyso_error_message("pobyso_parse",
66
                        "EMPTY_STRING_ARGUMENT",
67
                        "The expression is an empty string");
68
    return(sollya_lib_error());
69
  }
70
  /* Search from the last char of the expression until, whichever happens
71
   * first:
72
   * a ";" is found;
73
   * a char  != ';' is found the the ";" is appended.
74
   * If the head of the string is reached before any of these two events happens
75
   * return an error.
76
   */
77
  for (i = expressionLength - 1 ; i >= 0 ; i--)
78
  {
79
    if (expression[i] == ';') /* Nothing special to do:
80
                                 try to parse the string*/
81
    {
82
      /* This ugly cast comes from a deficient definition in Sollya:
83
         sollya_lib_string does not take a const char * argument. */
84
      expressionStringSa = sollya_lib_string((char*)expression);
85
      expressionSa = sollya_lib_parse(expressionStringSa);
86
      sollya_lib_free(expressionStringSa);
87
      return(expressionSa);
88
    }
89
    else
90
    {
91
      if (expression[i] == ' ' || expression[i] == '\t') /* A blank,
92
                                                           just continue. */
93
      {
94
        continue;
95
      }
96
      else /* a character != ';' and from a blank: create the ';'ed string. */
97
      {
98
        /* Create a new string for the expression, add the ";" and
99
         * and call sollya_lib_parse_string. */
100
        expressionWithSemiCo = calloc(i + 3, sizeof(char));
101
        if (expressionWithSemiCo == NULL)
102
        {
103
          pobyso_error_message("pobyso_parse",
104
                                "MEMORY_ALLOCATION_ERROR",
105
                                "Could not allocate the expression string");
106
          return(sollya_lib_error());
107
        }
108
        strncpy(expressionWithSemiCo, expression, i + 1);
109
        expressionWithSemiCo[i + 1] = ';';
110
        expressionWithSemiCo[i + 2] = '\0';
111
        expressionStringSa = sollya_lib_string(expressionWithSemiCo);
112
        expressionSa = sollya_lib_parse(expressionStringSa);
113
        free(expressionWithSemiCo);
114
        sollya_lib_free(expressionStringSa);
115
        return(expressionSa);
116
      } /* End character != ';' and from a blank. */
117
    /* Create a new string for the expression, add the ";" and
118
     * and call sollya_lib_parse_string. */
119
    } /* End else. */
120
  } /* End for. */
121
  /* We get here, it is because we did not find any char == anything different
122
   * from ' ' or '\t': the string is empty.
123
   */
124
  pobyso_error_message("pobyso_parse_string",
125
                       "ONLY_BLANK_ARGUMENT",
126
                        "The expression is only made of blanks");
127
  return(sollya_lib_error());
128

    
129
} /* pobyso_parse_string */
130

    
131
/* @see pobyso.h#pobyso_parse_string*/
132
pobyso_func_exp_t
133
pobyso_parse_string(const char* expression)
134
{
135
  int expressionLength, i;
136
  char *expressionWithSemiCo;
137
  sollya_obj_t expressionSa;
138

    
139
  /* Arguments check. */
140
  if (expression == NULL)
141
  {
142
    pobyso_error_message("pobyso_parse_string",
143
                        "NULL_POINTER_ARGUMENT",
144
                        "The expression is a NULL pointer");
145
    return(sollya_lib_error());
146
  }
147
  expressionLength = strlen(expression);
148
  if (expressionLength == 0)
149
  {
150
    pobyso_error_message("pobyso_parse_string",
151
                        "EMPTY_STRING_ARGUMENT",
152
                        "The expression is an empty string");
153
    return(sollya_lib_error());
154
  }
155
  /* Search from the last char of the expression until, whichever happens
156
   * first:
157
   * a ";" is found;
158
   * a char  != ';' is found the the ";" is appended.
159
   * If the head of the string is reached before any of these two events happens
160
   * return an error.
161
   */
162
  for (i = expressionLength - 1 ; i >= 0 ; i--)
163
  {
164
    if (expression[i] == ';') /* Nothing special to do:
165
                                 try to parse the string*/
166
    {
167
      expressionSa = sollya_lib_parse_string(expression);
168
      return(expressionSa);
169
    }
170
    else
171
    {
172
      if (expression[i] == ' ' || expression[i] == '\t') /* A blank,
173
                                                           just continue. */
174
      {
175
        continue;
176
      }
177
      else /* a character != ';' and from a blank: create the ';'ed string. */
178
      {
179
        /* Create a new string for the expression, add the ";" and
180
         * and call sollya_lib_parse_string. */
181
        expressionWithSemiCo = calloc(i + 3, sizeof(char));
182
        if (expressionWithSemiCo == NULL)
183
        {
184
          pobyso_error_message("pobyso_parse_string",
185
                                "MEMORY_ALLOCATION_ERROR",
186
                                "Could not allocate the expression string");
187
          return(sollya_lib_error());
188
        }
189
        strncpy(expressionWithSemiCo, expression, i + 1);
190
        expressionWithSemiCo[i + 1] = ';';
191
        expressionWithSemiCo[i + 2] = '\0';
192
        expressionSa = sollya_lib_parse_string(expressionWithSemiCo);
193
        free(expressionWithSemiCo);
194
        return(expressionSa);
195
      } /* End character != ';' and from a blank. */
196
    /* Create a new string for the expression, add the ";" and
197
     * and call sollya_lib_parse_string. */
198
    } /* End else. */
199
  } /* End for. */
200
  /* We get here, it is because we did not find any char == anything different
201
   * from ' ' or '\t': the string is empty.
202
   */
203
  pobyso_error_message("pobyso_parse_string",
204
                       "ONLY_BLANK_ARGUMENT",
205
                        "The expression is only made of blanks");
206
  return(sollya_lib_error());
207

    
208
} /* pobyso_parse_string */
209

    
210
sollya_verbosity_t
211
pobyso_set_verbosity_off()
212
{
213
  sollya_obj_t verbosityLevelZero;
214
  sollya_obj_t currentVerbosityLevel = NULL;
215

    
216
  currentVerbosityLevel = sollya_lib_get_verbosity();
217
  verbosityLevelZero = sollya_lib_constant_from_int(0);
218
  sollya_lib_set_verbosity(verbosityLevelZero);
219
  sollya_lib_clear_obj(verbosityLevelZero);
220
  return(currentVerbosityLevel);
221
} /* End of pobyso_set_verbosity_off. */
222

    
223
sollya_verbosity_t
224
pobyso_set_verbosity_to(sollya_obj_t newVerbosityLevel)
225
{
226
  sollya_obj_t currentVerbosityLevel = NULL;
227
  if (newVerbosityLevel == NULL)
228
  {
229
    pobyso_error_message("pobyso_set_verbosity_to",
230
                        "NULL_POINTER_ARGUMENT",
231
                        "The new verbosity level is a NULL pointer");
232
    return(sollya_lib_error());
233
  }
234
  currentVerbosityLevel = sollya_lib_get_verbosity();
235
  sollya_lib_set_verbosity(newVerbosityLevel);
236
  return(currentVerbosityLevel);
237
} /* End of pobyso_set_verbosity_to. */
238

    
239
/* Attic from the sollya_lib < 4. */
240
#if 0
241
chain*
242
pobyso_create_canonical_monomials_base(const unsigned int degree)
243
{
244
  int i    = 0;
245
  chain *monomials  = NULL;
246
  node  *monomial   = NULL;
247

248
  for(i = degree ; i >= 0  ; i--)
249
  {
250
     monomial   = makePow(makeVariable(), makeConstantDouble((double)i));
251
     monomials  = addElement(monomials, monomial);
252
     fprintf(stderr, "pobyso_create_canonical_monomials_base: %u\n", i);
253
  }
254
  if (monomials == NULL)
255
  {
256
    pobyso_error_message("pobyso_create_canonical_monomial_base",
257
                        "CHAIN_CREATION_ERROR",
258
                        "Could not create the monomials chain");
259
    return(NULL);
260
  }
261
  return(monomials);
262
} /* End pobyso_create_canonical_monomials_base. */
263

264
chain*
265
pobyso_create_chain_from_int_array(int* intArray,
266
                                    const unsigned int arrayLength)
267
{
268
  int i = 0;
269
  chain *newChain = NULL;
270
  int *currentInt;
271

272
  if (arrayLength == 0) return(NULL);
273
  if (intArray == NULL)
274
  {
275
    pobyso_error_message("pobyso_create_chain_from_int_array",
276
                        "NULL_POINTER_ARGUMENT",
277
                        "The array is a NULL pointer");
278
    return(NULL);
279
  }
280
  for (i = arrayLength - 1 ; i >= 0 ; i--)
281
  {
282
    currentInt = malloc(sizeof(int));
283
    if (currentInt == NULL)
284
    {
285
      pobyso_error_message("pobyso_create_chain_from_int_array",
286
                          "MEMORY_ALLOCATION_ERROR",
287
                          "Could not allocate one of the integers");
288
      freeChain(newChain, free);
289
      return(NULL);
290
    }
291
    *currentInt = intArray[i];
292
    newChain = addElement(newChain, currentInt);
293
  }
294
  return(newChain);
295
} // End pobyso_create_chain_from_int_array. */
296

297
chain*
298
pobyso_create_chain_from_unsigned_int_array(unsigned int* intArray,
299
                                        const unsigned int arrayLength)
300
{
301
  int i = 0;
302
  chain *newChain = NULL;
303
  unsigned int *currentInt;
304

305
  /* Argument checking. */
306
  if (arrayLength == 0) return(NULL);
307
  if (intArray == NULL)
308
  {
309
    pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
310
                        "NULL_POINTER_ARGUMENT",
311
                        "The array is a NULL pointer");
312
    return(NULL);
313
  }
314
  for (i = arrayLength - 1 ; i >= 0 ; i--)
315
  {
316
    currentInt = malloc(sizeof(unsigned int));
317
    if (currentInt == NULL)
318
    {
319
      pobyso_error_message("pobyso_create_chain_from_unsigned_int_array",
320
                          "MEMORY_ALLOCATION_ERROR",
321
                          "Could not allocate one of the integers");
322
      freeChain(newChain, free);
323
      return(NULL);
324
    }
325
    *currentInt = intArray[i];
326
    newChain = addElement(newChain, currentInt);
327
  }
328
  return(newChain);
329
} // End pobyso_create_chain_from_unsigned_int_array. */
330

331
node*
332
pobyso_differentiate(node *functionNode)
333
{
334
  /* Argument checking. */
335
  node *differentialNode;
336
  if (functionNode == NULL)
337
  {
338
    pobyso_error_message("pobyso_differentiate",
339
                        "NULL_POINTER_ARGUMENT",
340
                        "The function to differentiate is a NULL pointer");
341
    return(NULL);
342
  }
343
  differentialNode = differentiate(functionNode);
344
  if (differentialNode == NULL)
345
  {
346
    pobyso_error_message("pobyso_differentiate",
347
                        "INTERNAL ERROR",
348
                        "Sollya could not differentiate the function");
349
  }
350
  return(differentialNode);
351
} // End pobyso_differentiate
352

353

354
int
355
pobyso_dirty_infnorm(mpfr_t infNorm,
356
                      node *functionNode,
357
                      mpfr_t lowerBound,
358
                      mpfr_t upperBound,
359
                      mp_prec_t precision)
360
{
361
  int functionCallResult;
362
  /* Arguments checking. */
363
  if (functionNode == NULL)
364
  {
365
    pobyso_error_message("pobyso_dirty_infnorm",
366
                        "NULL_POINTER_ARGUMENT",
367
                        "The function to compute is a NULL pointer");
368
    return(1);
369
  }
370
  if (mpfr_cmp(lowerBound, upperBound) > 0)
371
  {
372
    pobyso_error_message("pobyso_dirty_infnorm",
373
                        "INCOHERENT_INPUT_DATA",
374
                        "The lower bond is greater than the upper bound");
375
    return(1);
376
  }
377
  /* Particular cases. */
378
  if (mpfr_cmp(lowerBound, upperBound) == 0)
379
  {
380
    functionCallResult = pobyso_evaluate_faithful(infNorm,
381
                                                  functionNode,
382
                                                  lowerBound,
383
                                                  precision);
384
    return(functionCallResult);
385
  }
386
  if (isConstant(functionNode))
387
  {
388
    functionCallResult = pobyso_evaluate_faithful(infNorm,
389
                                                  functionNode,
390
                                                  lowerBound,
391
                                                  precision);
392
    if (!functionCallResult)
393
    {
394
      mpfr_abs(infNorm, infNorm, MPFR_RNDN);
395
    }
396
    return(functionCallResult);
397
  }
398
  uncertifiedInfnorm(infNorm,
399
                      functionNode,
400
                      lowerBound,
401
                      upperBound,
402
                      POBYSO_DEFAULT_POINTS,
403
                      precision);
404
  return(0);
405
} /* End pobyso_dirty_infnorm. */
406

407
int
408
pobyso_evaluate_faithful(mpfr_t faithfulEvaluation,
409
                          node *nodeToEvaluate,
410
                          mpfr_t argument,
411
                          mpfr_prec_t precision)
412
{
413
  /* Check input arguments. */
414
  if (nodeToEvaluate == NULL)
415
  {
416
    pobyso_error_message("pobyso_evaluate_faithful",
417
                        "NULL_POINTER_ARGUMENT",
418
                        "nodeToEvaluate is a NULL pointer");
419
    return(1);
420
  }
421
  evaluateFaithful(faithfulEvaluation,
422
                   nodeToEvaluate,
423
                   argument,
424
                   precision);
425
  return(0);
426
} /* End pobyso_evaluate_faithfull. */
427

428
chain*
429
pobyso_find_zeros(node *function,
430
                  mpfr_t *lower_bound,
431
                  mpfr_t *upper_bound)
432
{
433
  mp_prec_t currentPrecision;
434
  mpfr_t currentDiameter;
435
  rangetype bounds;
436

437
  currentPrecision = getToolPrecision();
438
  mpfr_init2(currentDiameter, currentPrecision);
439

440
  bounds.a = lower_bound;
441
  bounds.b = upper_bound;
442

443
  if (bounds.a == NULL || bounds.b == NULL)
444
  {
445
    pobyso_error_message("pobyso_find_zeros",
446
                        "MEMORY_ALLOCATION_ERROR",
447
                        "Could not allocate one of the bounds");
448
    return(NULL);
449
  }
450
  return(findZerosFunction(function,
451
                            bounds,
452
                            currentPrecision,
453
                            currentDiameter));
454
} /* End pobyso_find_zeros. */
455

456
void
457
pobyso_free_chain_of_nodes(chain *theChainOfNodes)
458
{
459
  node *currentNode           = NULL;
460
  chain *currentChainElement  = NULL;
461
  chain *nextChainElement     = NULL;
462

463
  nextChainElement = theChainOfNodes;
464

465
  while(nextChainElement != NULL)
466
  {
467
    currentChainElement = nextChainElement;
468
    currentNode = (node*)(currentChainElement->value);
469
    nextChainElement = nextChainElement->next;
470
    free_memory(currentNode);
471
    free((void*)(currentChainElement));
472
  }
473
} /* End pobyso_free_chain_of_nodes. */
474

475
void
476
pobyso_free_range(rangetype range)
477
{
478

479
  mpfr_clear(*(range.a));
480
  mpfr_clear(*(range.b));
481
  free(range.a);
482
  free(range.b);
483
} /* End pobyso_free_range. */
484

485
node*
486
pobyso_fp_minimax_canonical_monomials_base(node *function,
487
                                      int degree,
488
                                      chain *formats,
489
                                      chain *points,
490
                                      mpfr_t lowerBound,
491
                                      mpfr_t upperBound,
492
                                      int fpFixedArg,
493
                                      int absRel,
494
                                      node *constPart,
495
                                      node *minimax)
496
{
497
  return(NULL);
498
} /* End pobyso_fp_minimax_canonical_monomials_base. */
499

500
node*
501
pobyso_parse_function(char *functionString,
502
                      char *freeVariableNameString)
503
{
504
  if (functionString == NULL || freeVariableNameString == NULL)
505
  {
506
    pobyso_error_message("pobyso_parse_function",
507
                        "NULL_POINTER_ARGUMENT",
508
                        "One of the arguments is a NULL pointer");
509
    return(NULL);
510
  }
511
  return(parseString(functionString));
512

513
} /* End pobyso_parse_function */
514

515
node*
516
pobyso_remez_approx_canonical_monomials_base_for_error(node *functionNode,
517
                                                  unsigned int mode,
518
                                                  mpfr_t lowerBound,
519
                                                  mpfr_t upperBound,
520
                                                  mpfr_t eps)
521
{
522
  node *weight              = NULL;
523
  node *bestApproxPolyNode  = NULL;
524
  node *bestApproxHorner    = NULL;
525
  node *errorNode           = NULL;
526
  rangetype degreeRange;
527
  mpfr_t quality;
528
  mpfr_t currentError;
529
  unsigned int degree;
530

531
  /* Check the parameters. */
532
  if (functionNode == NULL)
533
  {
534
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
535
                        "NULL_POINTER_ARGUMENT",
536
                        "functionNode is a NULL pointer");
537
    return(NULL);
538
  }
539
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
540
  {
541
    pobyso_error_message("remezApproxCanonicalMonomialsBaseForError",
542
                        "INCOHERENT_INPUT_DATA",
543
                        "the lower_bound >= upper_bound");
544
    return(NULL);
545
  }
546
  /* Set the weight. */
547
  if (mode == POBYSO_ABSOLUTE)
548
  {
549
    /* Set the weight to 1 for the ABSOLUTE_MODE. */
550
    weight = makeConstantDouble(1.0);
551
  }
552
  else
553
  {
554
    if (mode == POBYSO_RELATIVE)
555
    {
556
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
557
                          "NOT_IMPLEMENTED",
558
                          "the search for relative error is not implemented yet");
559
      return(NULL);
560
    }
561
    else
562
    {
563
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
564
                          "INCOHERENT_INPUT_DATA",
565
                          "the mode is node of POBYSO_ABOLUTE or POBYSO_RELATIVE");
566
      return(NULL);
567
    }
568
  }
569
  //fprintf(stderr, "\n\n\n******* I'm here! ********\n\n\n");
570
  degreeRange = guessDegree(functionNode,
571
                            weight,
572
                            lowerBound,
573
                            upperBound,
574
                            eps,
575
                            POBYSO_GUESS_DEGREE_BOUND);
576
  degree = mpfr_get_ui(*(degreeRange.a), MPFR_RNDN);
577
  //fprintf(stderr, "\n\n\n******* I'm back! ********\n\n\n");
578
  fprintf(stderr, "Guessed degree: ");
579
  mpfr_out_str(stderr, 10, 17, *(degreeRange.a), MPFR_RNDN);
580
  fprintf(stderr, " - as int: %u\n", degree);
581
  /* Reduce the degree by 1 in the foolish hope it could work. */
582
  if (degree > 0) degree--;
583
  /* Both elements of degreeRange where "inited" within guessDegree. */
584
  mpfr_clear(*(degreeRange.a));
585
  mpfr_clear(*(degreeRange.b));
586
  free(degreeRange.a);
587
  free(degreeRange.b);
588
  /* Mimic the default behavior of interactive Sollya. */
589
  mpfr_init(quality);
590
  mpfr_set_d(quality, 1e-5, MPFR_RNDN);
591
  mpfr_init2(currentError, getToolPrecision());
592
  mpfr_set_inf(currentError,1);
593

594
  /* Try to refine the initial guess: loop with increasing degrees until
595
   * we find a satisfactory one. */
596
  while(mpfr_cmp(currentError, eps) > 0)
597
  {
598
    /* Get rid of the previous polynomial, if any. */
599
    if (bestApproxPolyNode != NULL)
600
    {
601
      free_memory(bestApproxPolyNode);
602
    }
603
    fprintf(stderr, "Degree: %u\n", degree);
604
    fprintf(stderr, "Calling pobyso_remez_canonical_monomials_base...\n");
605
    /* Try to find a polynomial with the guessed degree. */
606
    bestApproxPolyNode = pobyso_remez_canonical_monomials_base(functionNode,
607
                                                            weight,
608
                                                            degree,
609
                                                            lowerBound,
610
                                                            upperBound,
611
                                                            quality);
612

613
    if (bestApproxPolyNode == NULL)
614
    {
615
      pobyso_error_message("computeRemezApproxCanonicalMonomialsBaseForError",
616
                          "INTERNAL_ERROR",
617
                          "could not compute the bestApproxPolyNode");
618
      mpfr_clear(currentError);
619
      mpfr_clear(quality);
620
      return(NULL);
621
    }
622

623
    setDisplayMode(DISPLAY_MODE_DECIMAL);
624
    fprintTree(stderr, bestApproxPolyNode);
625
    fprintf(stderr, "\n\n");
626

627
    errorNode = makeSub(copyTree(functionNode), copyTree(bestApproxPolyNode));
628
    /* Check the error with the computed polynomial. */
629
    uncertifiedInfnorm(currentError,
630
                        errorNode,
631
                        lowerBound,
632
                        upperBound,
633
                        POBYSO_INF_NORM_NUM_POINTS,
634
                        getToolPrecision());
635
    fprintf(stderr, "Inf norm: ");
636
    mpfr_out_str(stderr, 10, 17, currentError, MPFR_RNDN);
637
    fprintf(stderr, "\n\n");
638
    /* Free the errorNode but not the bestApproxPolyNode (we need it if
639
     * we exit the loop at the next iteration). */
640
    free_memory(errorNode);
641
    degree++;
642
  }
643
  /* Use an intermediate variable, since horner() creates a new node
644
   * and does not reorder the argument "in place". This allows for the memory
645
   * reclaim of bestApproxHorner.
646
   */
647
  bestApproxHorner = horner(bestApproxPolyNode);
648
  free_memory(bestApproxPolyNode);
649
  mpfr_clear(currentError);
650
  mpfr_clear(quality);
651
  free_memory(weight);
652
  return(bestApproxHorner);
653
} /* End pobyso_remez_approx_canonical_monomials_base_for_error */
654

655
node*
656
pobyso_remez_canonical_monomials_base(node *function,
657
                                     node *weight,
658
                                     unsigned int degree,
659
                                     mpfr_t lowerBound,
660
                                     mpfr_t upperBound,
661
                                     mpfr_t quality)
662
{
663
  node  *bestApproxPoly = NULL;
664
  chain *monomials      = NULL;
665
  chain *curMonomial    = NULL;
666

667
  mpfr_t satisfying_error;
668
  mpfr_t target_error;
669

670
  /* Argument checking */
671
  /* Function tree. */
672
  if (function == NULL)
673
  {
674
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
675
                        "NULL_POINTER_ARGUMENT",
676
                        "the \"function\" argument is a NULL pointer");
677
    return(NULL);
678
  }
679
  if (weight == NULL)
680
  {
681
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
682
                        "NULL_POINTER_ARGUMENT",
683
                        "the \"weight\" argument is a NULL pointer");
684
    return(NULL);
685
  }
686
  /* Check the bounds. */
687
  if (mpfr_cmp(lowerBound, upperBound) >= 0)
688
  {
689
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
690
                        "INCOHERENT_IMPUT_DATA",
691
                        "the lower_bound >= upper_bound");
692
    return(NULL);
693
  }
694
  /* The quality must be a non null positive number. */
695
  if (mpfr_sgn(quality) <= 0)
696
  {
697
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
698
                        "INCOHERENT_INPUT_DATA",
699
                        "the quality <= 0");
700
  }
701
  /* End argument checking. */
702
  /* Create the monomials nodes chains. */
703
  monomials = pobyso_create_canonical_monomials_base(degree);
704
  fprintf(stderr, "monomials chain length = %d\n", lengthChain(monomials));
705
  if (monomials == NULL || (lengthChain(monomials) != degree + 1))
706
  {
707
    pobyso_error_message("pobyso_remez_canonical_monomials_base",
708
                        "CHAIN_CREATION_ERROR",
709
                        "could not create the monomials chain");
710
    return(NULL);
711
  }
712
  curMonomial = monomials;
713

714
  while (curMonomial != NULL)
715
  {
716
    fprintf(stderr, "monomial tree: ");
717
    //mpfr_out_str(stderr, 10, 17, *((mpfr_t*)((node*)(curMonomial->value))->value), MPFR_RNDN);
718
    fprintTree(stderr, (node*)(curMonomial->value));
719
    fprintf(stderr, "\n");
720
    curMonomial = curMonomial->next;
721
  }
722

723
  /* Deal with NULL weight. */
724
  if (weight == NULL)
725
  {
726
    weight = makeConstantDouble(1.0);
727
  }
728
  /* Compute the best polynomial with the required quality.
729
     The behavior is as if satisfying error and target_error had
730
     not been used.*/
731
  mpfr_init(satisfying_error);
732
  mpfr_init(target_error);
733
  mpfr_set_str(satisfying_error, "0", 10, MPFR_RNDN);
734
  mpfr_set_inf(target_error, 1);
735

736

737
  fprintf(stderr, "satisfying_error: ");
738
  mpfr_out_str(stderr, 10, 17, satisfying_error, MPFR_RNDN);
739
  fprintf(stderr, ".\n");
740
  fprintf(stderr, "target_error: ");
741
  mpfr_out_str(stderr, 10, 17, target_error,MPFR_RNDN);
742
  fprintf(stderr, ".\n");
743

744
  fprintf(stderr,
745
          "current precision: %li\n", getToolPrecision());
746
  /* Call the Sollya function. */
747
  bestApproxPoly = remez(function,
748
                          weight,
749
                          monomials,
750
                          lowerBound,
751
                          upperBound,
752
                          quality,
753
                          satisfying_error,
754
                          target_error,
755
                          getToolPrecision());
756

757
  mpfr_clear(satisfying_error);
758
  mpfr_clear(target_error);
759
  pobyso_free_chain_of_nodes(monomials);
760

761
  return(bestApproxPoly);
762
} /* End pobyso_remez_canonical_monomials_base. */
763

764
#endif
765

    
766
void
767
pobyso_error_message(char *functionName, char *messageName, char* message)
768
{
769
  fprintf(stderr, "?%s: %s.\n%s.\n", functionName, messageName, message);
770
} /* End pobyso_error_message */