Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (23,26 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

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

    
54
  /* Arguments check. */
55
  if (expression == NULL)
56
  {
57
    pobyso_error_message("pobyso_parse_string",
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_string",
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
      expressionSa = sollya_lib_parse_string(expression);
83
      return expressionSa;
84
    }
85
    else
86
    {
87
      if (expression[i] == ' ' || expression[i] == '\t') /* A blank,
88
                                                           just continue. */
89
      {
90
        continue;
91
      }
92
      else /* a character != ';' and from a blank: create the ';'ed string. */
93
      {
94
        /* Create a new string for the expression, add the ";" and
95
         * and call sollya_lib_parse_string. */
96
        expressionWithSemiCo = calloc(i + 3, sizeof(char));
97
        if (expressionWithSemiCo == NULL)
98
        {
99
          pobyso_error_message("pobyso_parse_string",
100
                                "MEMORY_ALLOCATION_ERROR",
101
                                "Could not allocate the expression string");
102
          return sollya_lib_error();
103
        }
104
        strncpy(expressionWithSemiCo, expression, i+1);
105
        expressionWithSemiCo[i + 1] = ';';
106
        expressionWithSemiCo[i + 2] = '\0';
107
        expressionSa = sollya_lib_parse_string(expressionWithSemiCo);
108
        free(expressionWithSemiCo);
109
        return expressionSa;
110
      } /* End character != ';' and from a blank. */
111
    /* Create a new string for the expression, add the ";" and
112
     * and call sollya_lib_parse_string. */
113
    } /* End else. */
114
  } /* End for. */
115
  /* We get here, it is because we did not find any char == anything different
116
   * from ' ' or '\t': the string is empty.
117
   */
118
  pobyso_error_message("pobyso_parse_string",
119
                       "ONLY_BLANK_ARGUMENT",
120
                        "The expression is only made of blanks");
121
  return(sollya_lib_error());
122

    
123
} /* pobyso_parse_string */
124

    
125
pobyso_func_exp_t
126
pobyso_remez_canonical_monomials_base(pobyso_func_exp_t function,
127
                                      long int degree,
128
                                      pobyso_range_t interval,
129
                                      pobyso_func_exp_t weight,
130
                                      double quality,
131
                                      pobyso_range_t bounds)
132
{
133
  sollya_obj_t  degreeSa = NULL;
134
  sollya_obj_t qualitySa = NULL;
135

    
136
  degreeSa = sollya_lib_constant_from_int(degree);
137
  qualitySa = sollya_lib_constant_from_double(quality);
138

    
139
  return NULL;
140
} /* End pobyso_remez_canonical_monomials_base. */
141

    
142
int
143
pobyso_set_canonical_on()
144
{
145
  pobyso_on_off_t currentCanonicalModeSo;
146
  int currentCanonicalMode;
147
  pobyso_on_off_t on;
148

    
149
  on = sollya_lib_on();
150
  currentCanonicalModeSo = sollya_lib_get_canonical();
151
  if (sollya_lib_is_on(currentCanonicalModeSo))
152
  {
153
    currentCanonicalMode = POBYSO_ON;
154
  }
155
  else
156
  {
157
    currentCanonicalMode = POBYSO_OFF;
158
  }
159
  sollya_lib_set_canonical(on);
160
  sollya_lib_clear_obj(on);
161
  sollya_lib_clear_obj(currentCanonicalModeSo);
162
  return currentCanonicalMode;
163
} /* End pobyso_set_canonical_on. */
164

    
165
pobyso_sollya_verbosity_t
166
pobyso_set_verbosity_off()
167
{
168
  sollya_obj_t verbosityLevelZero;
169
  sollya_obj_t currentVerbosityLevel = NULL;
170

    
171
  currentVerbosityLevel = sollya_lib_get_verbosity();
172
  verbosityLevelZero = sollya_lib_constant_from_int(0);
173
  sollya_lib_set_verbosity(verbosityLevelZero);
174
  sollya_lib_clear_obj(verbosityLevelZero);
175
  return(currentVerbosityLevel);
176
} /* End of pobyso_set_verbosity_off. */
177

    
178
pobyso_sollya_verbosity_t
179
pobyso_set_verbosity_to(pobyso_sollya_verbosity_t newVerbosityLevel)
180
{
181
  sollya_obj_t currentVerbosityLevel = NULL;
182
  if (newVerbosityLevel == NULL)
183
  {
184
    pobyso_error_message("pobyso_set_verbosity_to",
185
                        "NULL_POINTER_ARGUMENT",
186
                        "The new verbosity level is a null pointer");
187
    return(sollya_lib_error());
188
  }
189
  currentVerbosityLevel = sollya_lib_get_verbosity();
190
  sollya_lib_set_verbosity(newVerbosityLevel);
191
  return(currentVerbosityLevel);
192
} /* End of pobyso_set_verbosity_to. */
193

    
194
pobyso_sollya_verbosity_t
195
pobyso_set_verbosity_to_int(int intVerbosityLevel)
196
{
197
  sollya_obj_t currentVerbosityLevel = NULL;
198
  sollya_obj_t newVerbosityLevel     = NULL;
199
  if (intVerbosityLevel < 0)
200
  {
201
    pobyso_error_message("pobyso_set_verbosity_to",
202
                        "INVALID_VALUE",
203
                        "The new verbosity level is a negative number");
204
    return(sollya_lib_error());
205
  }
206
  newVerbosityLevel = sollya_lib_constant_from_int(intVerbosityLevel);
207
  currentVerbosityLevel = sollya_lib_get_verbosity();
208
  sollya_lib_set_verbosity(newVerbosityLevel);
209
  return(currentVerbosityLevel);
210
} /* End of pobyso_set_verbosity_to_int. */
211

    
212
/* Attic from the sollya_lib < 4. */
213
#if 0
214
chain*
215
pobyso_create_canonical_monomials_base(const unsigned int degree)
216
{
217
  int i    = 0;
218
  chain *monomials  = NULL;
219
  node  *monomial   = NULL;
220

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

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

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

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

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

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

326

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

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

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

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

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

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

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

436
  nextChainElement = theChainOfNodes;
437

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

448
void
449
pobyso_free_range(rangetype range)
450
{
451

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

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

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

486
} /* End pobyso_parse_function */
487

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

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

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

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

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

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

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

640
  mpfr_t satisfying_error;
641
  mpfr_t target_error;
642

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

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

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

709

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

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

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

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

737
#endif
738

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