Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (24,44 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_function_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_function_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
  if (newVerbosityLevel == NULL)
227
  {
228
    pobyso_error_message("pobyso_set_verbosity_to",
229
                        "NULL_POINTER_ARGUMENT",
230
                        "The new verbosity level is a NULL pointer");
231
    return(sollya_lib_error());
232
  }
233
  sollya_lib_set_verbosity(newVerbosityLevel);
234
} /* End of pobyso_set_verbosity_to. */
235

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

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

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

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

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

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

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

350

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

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

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

434
  currentPrecision = getToolPrecision();
435
  mpfr_init2(currentDiameter, currentPrecision);
436

437
  bounds.a = lower_bound;
438
  bounds.b = upper_bound;
439

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

453
void
454
pobyso_free_chain_of_nodes(chain *theChainOfNodes)
455
{
456
  node *currentNode           = NULL;
457
  chain *currentChainElement  = NULL;
458
  chain *nextChainElement     = NULL;
459

460
  nextChainElement = theChainOfNodes;
461

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

472
void
473
pobyso_free_range(rangetype range)
474
{
475

476
  mpfr_clear(*(range.a));
477
  mpfr_clear(*(range.b));
478
  free(range.a);
479
  free(range.b);
480
} /* End pobyso_free_range. */
481

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

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

510
} /* End pobyso_parse_function */
511

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

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

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

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

620
    setDisplayMode(DISPLAY_MODE_DECIMAL);
621
    fprintTree(stderr, bestApproxPolyNode);
622
    fprintf(stderr, "\n\n");
623

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

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

664
  mpfr_t satisfying_error;
665
  mpfr_t target_error;
666

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

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

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

733

734
  fprintf(stderr, "satisfying_error: ");
735
  mpfr_out_str(stderr, 10, 17, satisfying_error, MPFR_RNDN);
736
  fprintf(stderr, ".\n");
737
  fprintf(stderr, "target_error: ");
738
  mpfr_out_str(stderr, 10, 17, target_error,MPFR_RNDN);
739
  fprintf(stderr, ".\n");
740

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

754
  mpfr_clear(satisfying_error);
755
  mpfr_clear(target_error);
756
  pobyso_free_chain_of_nodes(monomials);
757

758
  return(bestApproxPoly);
759
} /* End pobyso_remez_canonical_monomials_base. */
760

761
#endif
762

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