Class: MPC

Inherits:
Numeric
  • Object
show all
Defined in:
ext/mpc.c,
ext/mpc.c,
ext/mpcrnd.c

Overview

GMP Multiple Precision Complex numbers

Instances of this class can store variables of the type mpc_t. This class also contains many methods that act as the functions for mpc_t variables, as well as a few methods that attempt to make this library more Ruby-ish.

Defined Under Namespace

Classes: Rnd

Constant Summary collapse

MPC_VERSION =
rb_str_new2(MPC_VERSION_STRING)
MPC_RNDNN =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(0))
MPC_RNDNZ =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(16))
MPC_RNDNU =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(32))
MPC_RNDND =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(48))
MPC_RNDZN =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(1))
MPC_RNDZZ =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(17))
MPC_RNDZU =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(33))
MPC_RNDZD =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(49))
MPC_RNDUN =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(2))
MPC_RNDUZ =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(18))
MPC_RNDUU =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(34))
MPC_RNDUD =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(50))
MPC_RNDDN =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(3))
MPC_RNDDZ =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(19))
MPC_RNDDU =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(35))
MPC_RNDDD =
rb_funcall (cMPC_Rnd, new_id, 1, INT2FIX(51))

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'ext/mpc.c', line 298

VALUE r_mpc_initialize(int argc, VALUE *argv, VALUE self)
{
  MP_COMPLEX *self_val;
  MP_FLOAT *arg_val_f;
  MP_COMPLEX *arg_val_c;
  unsigned long prec = 0;
  mpfr_prec_t prec_re = 0;
  mpfr_prec_t prec_im = 0;
  mpc_rnd_t rnd_mode_val = r_mpc_default_rounding_mode;
  VALUE arg;

  mpc_get_struct (self, self_val);

  if (argc==0) {
    mpc_init2 (self_val, mpfr_get_default_prec());
    mpc_set_si (self_val, 0, rnd_mode_val);
    return Qnil;
  }

  arg = argv[0];

  // argc = 2 ==> argv[0] is value, argv[1] is prec
  //           OR argv[0] is value, argv[1] is rnd
  if (argc >= 2) {
    if (FIXNUM_P (argv[1])) {
      if (FIX2INT (argv[1]) >= 2)
        prec = FIX2INT (argv[1]);
      else {
        mpc_init2 (self_val, mpfr_get_default_prec());
        rb_raise (rb_eRangeError, "prec must be at least 2");
      }
    } else if (MPCRND_P (argv[1])) {
      rnd_mode_val = r_get_mpc_rounding_mode(argv[1]);
    } else {
      mpc_init2 (self_val, mpfr_get_default_prec());
      rb_raise (rb_eTypeError, "don't know how to interpret argument 1, a %s", rb_class2name (rb_class_of (argv[1])));
    }
  // if no precision provided, but an mpfr_t is passed as value, use its prec
  } else if (GMPF_P (arg)) {
    mpf_get_struct (arg, arg_val_f);
    prec = mpf_get_prec (arg_val_f);
  // if no precision provided, but an mpc_t is passed as value, use its prec
  } else if (MPC_P (arg)) {
    mpc_get_struct (arg, arg_val_c);
    mpc_get_prec2 (&prec_re, &prec_im, arg_val_c);
  }

  // argc = 3 ==> argv[0] is value, argv[1] is prec_r, argv[2] is prec_i
  //           OR argv[0] is value, argv[1] is prec,   argv[2] is rnd
  if (argc == 3) {
    if (MPCRND_P (argv[1])) {
      mpc_init2 (self_val, mpfr_get_default_prec());
      rb_raise (rb_eArgError, "the rounding mode should be the last argument");
    } else if (FIXNUM_P (argv[2])) {
      if (FIX2INT (argv[2]) >= 0) {
        // argv[1] was actually prec_r and //argv[2] is prec_i
        prec_re = (mpfr_prec_t) prec;
        prec_im = FIX2INT (argv[2]);
        prec = 0;
      } else {
        mpc_init2 (self_val, mpfr_get_default_prec());
        rb_raise (rb_eRangeError, "prec_im must be non-negative");
      }
    } else if (MPCRND_P (argv[2])) {
      rnd_mode_val = r_get_mpc_rounding_mode(argv[2]);
    } else {
      mpc_init2 (self_val, mpfr_get_default_prec());
      rb_raise (rb_eTypeError, "don't know how to interpret argument 2, a %s", rb_class2name (rb_class_of (argv[2])));
    }
  }

  // argc = 4 ==> argv[0] is value, argv[1] is prec_r, argv[2] is prec_i, argv[3] is rnd
  // TODO

  if (prec == 0 && prec_re == 0)
    /* precision was not specified */
    mpc_init2 (self_val, mpfr_get_default_prec());
  else if (prec == 0)
    /* precision was specified in two parts */
    mpc_init3 (self_val, prec_re, prec_im);
  else
    mpc_init2 (self_val, prec);

  if (STRING_P (argv[0])) {
    // unfortunately, we cannot accept an explicit base, as we do in r_gmpf_initialize.
    // #new(c, prec, base) would be indistinguishable from #new(c, prec_r, prec_i).
    // TODO allow this behavior via something like #new_str or String#to_mpc
    mpc_set_str (self_val, StringValuePtr(arg), 0, rnd_mode_val);
    return Qnil;
  }

  //if (MPC_P(arg)) {
  //  mpc_get_struct (arg, arg_val_c);
  //  mpc_set (self_val, arg_val_c, rnd_mode_val);
  //} else {
    mpc_set_value (self_val, arg, rnd_mode_val);
  //}

  return Qnil;
}

Class Method Details

.new(value = 0) ⇒ Object

Creates a new MPC complex number, with value as its value, converting where necessary. value must be an instance of one of the following classes:

  • MPC
  • GMP::Z
  • GMP::F
  • Fixnum
  • String
  • Bignum

Examples:

MPC.new(5)                   #=> (5,0)
MPC.new(1.111)               #=> (1.111,0)
MPC.new(5, 32)               #=> (5,0) with precision 32
MPC.new([1.0, 1.0], 32, 64)  #=> (1.0,1.0) with real precision 32, imag precision 64


283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'ext/mpc.c', line 283

VALUE r_mpcsg_new(int argc, VALUE *argv, VALUE klass)
{
  MP_COMPLEX *res;
  VALUE res_val;
  (void)klass;

  if (argc > 3)
    rb_raise (rb_eArgError, "wrong # of arguments (%d for 0, 1, 2, or 3)", argc);

  mpc_make_struct (res_val, res);
  rb_obj_call_init (res_val, argc, argv);

  return res_val;
}

Instance Method Details

#*(arg_val) ⇒ Object



866
867
868
869
870
871
872
873
874
875
876
877
# File 'ext/mpc.c', line 866

VALUE r_mpc_mul2(VALUE self_val, VALUE arg_val)
{
  MP_COMPLEX *self;

  mpfr_prec_t res_real_prec, res_imag_prec;

  mpc_get_struct(self_val, self);
  res_real_prec = mpfr_get_prec(mpc_realref(self));
  res_imag_prec = mpfr_get_prec(mpc_imagref(self));

  return r_mpc_mul_do_the_work(self_val, arg_val, MPC_RNDNN, res_real_prec, res_imag_prec);
}

#**(arg_val) ⇒ Object



1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
# File 'ext/mpc.c', line 1146

VALUE r_mpc_pow2(VALUE self_val, VALUE arg_val)
{
  MP_COMPLEX *self, *res;
  mpc_rnd_t rnd_mode;
  VALUE res_val;
  mpc_get_struct (self_val, self);
  mpc_make_struct (res_val, res);
  mpc_init3 (res, mpfr_get_prec (mpc_realref (self)), mpfr_get_prec (mpc_imagref (self)));
  rnd_mode = r_mpc_default_rounding_mode;

  return r_mpc_pow_compute(self, arg_val, res_val, rnd_mode);
}

#+(arg_val) ⇒ Object



713
714
715
716
717
718
719
720
721
722
723
724
# File 'ext/mpc.c', line 713

VALUE r_mpc_add2(VALUE self_val, VALUE arg_val)
{
  MP_COMPLEX *self;

  mpfr_prec_t res_real_prec, res_imag_prec;

  mpc_get_struct(self_val, self);
  res_real_prec = mpfr_get_prec(mpc_realref(self));
  res_imag_prec = mpfr_get_prec(mpc_imagref(self));

  return r_mpc_add_do_the_work(self_val, arg_val, MPC_RNDNN, res_real_prec, res_imag_prec);
}

#-(arg_val) ⇒ Object



784
785
786
787
788
789
790
791
792
793
794
795
796
797
# File 'ext/mpc.c', line 784

VALUE r_mpc_sub2(VALUE self_val, VALUE arg_val)
{
  MP_COMPLEX *self, *res;
  VALUE res_val;
  mpfr_prec_t res_real_prec, res_imag_prec;

  mpc_get_struct (self_val, self);
  res_real_prec = mpfr_get_prec (mpc_realref (self));
  res_imag_prec = mpfr_get_prec (mpc_imagref (self));

  mpc_make_struct_init3 (res_val, res, res_real_prec, res_imag_prec);

  return r_mpc_sub_compute (self, arg_val, res_val, r_mpc_default_rounding_mode);
}

#-@Object

#/(arg_val) ⇒ Object



982
983
984
985
986
987
988
989
990
991
992
993
# File 'ext/mpc.c', line 982

VALUE r_mpc_div2(VALUE self_val, VALUE arg_val)
{
  MP_COMPLEX *self;

  mpfr_prec_t res_real_prec, res_imag_prec;

  mpc_get_struct(self_val, self);
  res_real_prec = mpfr_get_prec(mpc_realref(self));
  res_imag_prec = mpfr_get_prec(mpc_imagref(self));

  return r_mpc_div_do_the_work(self_val, arg_val, MPC_RNDNN, res_real_prec, res_imag_prec);
}

#<=>(arg_val) ⇒ Object

Comparison Functions



558
559
560
561
562
563
564
565
# File 'ext/mpc.c', line 558

VALUE r_mpc_cmp(VALUE self_val, VALUE arg_val)
{
  MP_COMPLEX *self;
  int res;
  mpc_get_struct (self_val, self);
  res = mpc_cmp_value (self, arg_val);
  return rb_assoc_new (INT2FIX (MPC_INEX_RE (res)), INT2FIX (MPC_INEX_IM (res)));
}

#==(arg_val) ⇒ Object



551
552
553
554
555
556
# File 'ext/mpc.c', line 551

VALUE r_mpc_eq(VALUE self_val, VALUE arg_val)
{
  MP_COMPLEX *self;
  mpc_get_struct (self_val, self);
  return (mpc_cmp_value (self, arg_val) == 0) ? Qtrue : Qfalse;
}

#absObject

#acosObject

#add(*args) ⇒ Object

Basic Arithmetic Functions



682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
# File 'ext/mpc.c', line 682

VALUE r_mpc_add(int argc, VALUE *argv, VALUE self_val)
{
  MP_COMPLEX *self;
  VALUE rnd_mode_val;
  VALUE  res_real_prec_val, res_imag_prec_val;
  VALUE arg_val;

  mpfr_prec_t real_prec, imag_prec;
  mpfr_prec_t res_real_prec, res_imag_prec;
  mpc_rnd_t rnd_mode;

  mpc_get_struct(self_val,self);
  real_prec = mpfr_get_prec(mpc_realref(self));
  imag_prec = mpfr_get_prec(mpc_imagref(self));

  //if (argc > 0 && TYPE(argv[0]) == T_HASH) {
  //  rb_mpc_get_hash_arguments (&rnd_mode, &real_prec, &imag_prec, argv[0]);
    //res_real_prec = real_prec;
    //res_imag_prec = imag_prec;
  //} else {
    rb_scan_args (argc, argv, "13", &arg_val, &rnd_mode_val, &res_real_prec_val, &res_imag_prec_val);

    r_mpc_set_default_args (rnd_mode_val, res_real_prec_val, res_imag_prec_val,
                           &rnd_mode,    &res_real_prec,    &res_imag_prec,
                                              real_prec,         imag_prec);
  //}

  //return res_val;
  return r_mpc_add_do_the_work(self_val, arg_val, rnd_mode, res_real_prec, res_imag_prec);
}

#argObject

#asinObject

#atanObject

#conjObject

#cosObject

#coshObject

#div(*args) ⇒ Object



951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
# File 'ext/mpc.c', line 951

VALUE r_mpc_div(int argc, VALUE *argv, VALUE self_val)
{
  MP_COMPLEX *self;
  VALUE rnd_mode_val;
  VALUE  res_real_prec_val, res_imag_prec_val;
  VALUE arg_val;

  mpfr_prec_t real_prec, imag_prec;
  mpfr_prec_t res_real_prec, res_imag_prec;
  mpc_rnd_t rnd_mode;

  mpc_get_struct(self_val,self);
  real_prec = mpfr_get_prec(mpc_realref(self));
  imag_prec = mpfr_get_prec(mpc_imagref(self));

  //if (argc > 0 && TYPE(argv[0]) == T_HASH) {
  //  rb_mpc_get_hash_arguments (&rnd_mode, &real_prec, &imag_prec, argv[0]);
    //res_real_prec = real_prec;
    //res_imag_prec = imag_prec;
  //} else {
    rb_scan_args (argc, argv, "13", &arg_val, &rnd_mode_val, &res_real_prec_val, &res_imag_prec_val);

    r_mpc_set_default_args (rnd_mode_val, res_real_prec_val, res_imag_prec_val,
                           &rnd_mode,    &res_real_prec,    &res_imag_prec,
                                              real_prec,         imag_prec);
  //}

  //return res_val;
  return r_mpc_div_do_the_work(self_val, arg_val, rnd_mode, res_real_prec, res_imag_prec);
}

#expObject

#fmaObject

#imagObject

#logObject

#log10Object

#mul(*args) ⇒ Object



835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
# File 'ext/mpc.c', line 835

VALUE r_mpc_mul(int argc, VALUE *argv, VALUE self_val)
{
  MP_COMPLEX *self;
  VALUE rnd_mode_val;
  VALUE res_real_prec_val, res_imag_prec_val;
  VALUE arg_val;

  mpfr_prec_t real_prec, imag_prec;
  mpfr_prec_t res_real_prec, res_imag_prec;
  mpc_rnd_t rnd_mode;

  mpc_get_struct(self_val,self);
  real_prec = mpfr_get_prec(mpc_realref(self));
  imag_prec = mpfr_get_prec(mpc_imagref(self));

  //if (argc > 0 && TYPE(argv[0]) == T_HASH) {
  //  rb_mpc_get_hash_arguments (&rnd_mode, &real_prec, &imag_prec, argv[0]);
    //res_real_prec = real_prec;
    //res_imag_prec = imag_prec;
  //} else {
    rb_scan_args (argc, argv, "13", &arg_val, &rnd_mode_val, &res_real_prec_val, &res_imag_prec_val);

    r_mpc_set_default_args (rnd_mode_val, res_real_prec_val, res_imag_prec_val,
                           &rnd_mode,    &res_real_prec,    &res_imag_prec,
                                              real_prec,         imag_prec);
  //}

  //return res_val;
  return r_mpc_mul_do_the_work(self_val, arg_val, rnd_mode, res_real_prec, res_imag_prec);
}

#mul_i(*args) ⇒ Object



920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
# File 'ext/mpc.c', line 920

VALUE r_mpc_mul_i(int argc, VALUE *argv, VALUE self_val)
{
  MP_COMPLEX *self, *res;
  VALUE rnd_mode_val;
  VALUE res_real_prec_val, res_imag_prec_val;
  VALUE sign_val, res_val;

  mpfr_prec_t real_prec, imag_prec;
  mpfr_prec_t res_real_prec, res_imag_prec;
  mpc_rnd_t rnd_mode;

  mpc_get_struct(self_val,self);
  real_prec = mpfr_get_prec(mpc_realref(self));
  imag_prec = mpfr_get_prec(mpc_imagref(self));

  rb_scan_args (argc, argv, "13", &sign_val, &rnd_mode_val, &res_real_prec_val, &res_imag_prec_val);

  r_mpc_set_default_args (rnd_mode_val, res_real_prec_val, res_imag_prec_val,
                         &rnd_mode,    &res_real_prec,    &res_imag_prec,
                                            real_prec,         imag_prec);

  if (! FIXNUM_P (sign_val))
    typeerror(X);

  mpc_make_struct_init3 (res_val, res, res_real_prec, res_imag_prec);
  mpc_mul_i (res, self, FIX2INT(sign_val), rnd_mode);

  return res_val;
}

#negObject

#normObject #norm(rounding_mode) ⇒ Object

Returns the norm of c (i.e., the square of its absolute value), as a GMP_F float (an MPFR float, really).



1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
# File 'ext/mpc.c', line 1099

VALUE r_mpc_norm(int argc, VALUE *argv, VALUE self)
{
  MP_COMPLEX *self_val;
  MP_FLOAT *norm_val;
  VALUE rnd_mode, norm;
  mpfr_prec_t pr=0, pi=0;
  mpc_rnd_t rnd_mode_val;

  mpc_get_struct (self, self_val);

  rb_scan_args (argc, argv, "01", &rnd_mode);
  if (NIL_P (rnd_mode)) { rnd_mode_val = r_mpc_default_rounding_mode; }
  else { rnd_mode_val = r_get_mpc_rounding_mode (rnd_mode); }

  mpf_make_struct (norm, norm_val);
  mpc_get_prec2 (&pr, &pi, self_val);
  mpfr_init2 (norm_val, pr);
  mpc_norm (norm_val, self_val, rnd_mode_val);
  return norm;
}

#pow(*args) ⇒ Object



1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
# File 'ext/mpc.c', line 1132

VALUE r_mpc_pow(int argc, VALUE *argv, VALUE self_val)
{
  MP_COMPLEX *self, *res;
  mpc_rnd_t rnd_mode;
  VALUE res_val;
  /* TODO: test for argc >= 1 */
  VALUE arg_val = argv[0];
  mpc_get_struct (self_val, self);
  mpc_make_struct (res_val, res);
  r_mpc_init_mpc_res_and_set_rnd_mode (&res, &rnd_mode, argc, argv, self, "13");

  return r_mpc_pow_compute(self, arg_val, res_val, rnd_mode);
}

#precObject

If the real and imaginary part of c have the same precision, it is returned. Otherwise, 0 is returned.



471
472
473
474
475
476
# File 'ext/mpc.c', line 471

VALUE r_mpc_prec(VALUE self_val)
{
  MP_COMPLEX *self;
  mpc_get_struct (self_val, self);
  return INT2NUM (mpc_get_prec (self));
}

#prec2Object

Returns the precision of the real part and imaginary part of c.



484
485
486
487
488
489
490
491
492
# File 'ext/mpc.c', line 484

VALUE r_mpc_prec2(VALUE self_val)
{
  MP_COMPLEX *self;
  mpfr_prec_t prec_re;
  mpfr_prec_t prec_im;
  mpc_get_struct (self_val, self);
  mpc_get_prec2 (&prec_re, &prec_im, self);
  return rb_assoc_new (INT2NUM (prec_re), INT2NUM (prec_im));
}

#projObject

#realObject

Projection and Decomposing Functions

#sinObject

Trigonometric Functions

#sinhObject

#sqrObject

#sqrtObject

Power Functions and Logarithm

#sub(*args) ⇒ Object



768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
# File 'ext/mpc.c', line 768

VALUE r_mpc_sub(int argc, VALUE *argv, VALUE self_val)
{
  MP_COMPLEX *self, *res;
  VALUE res_val;
  mpc_rnd_t rnd_mode;
  /* TODO: test for argc >= 1 */
  VALUE arg_val = argv[0];

  mpc_get_struct(self_val,self);

  mpc_make_struct (res_val, res);
  r_mpc_init_mpc_res_and_set_rnd_mode (&res, &rnd_mode, argc, argv, self, "13");

  return r_mpc_sub_compute (self, arg_val, res_val, rnd_mode);
}

#tanObject

TODO rb_define_method (cMPC, "sin_cos", r_mpc_sin_cos, -1);

#tanhObject

#to_sObject

Returns the decimal representation of the real part and imaginary part of c, as a String.



505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
# File 'ext/mpc.c', line 505

VALUE r_mpc_to_s(int argc, VALUE *argv, VALUE self_val)
{
  MP_COMPLEX *self;
  char *str;
  VALUE base_val, sig_figs_val, rnd_mode_val, res_val;
  int base;
  size_t sig_figs;
  mpc_rnd_t rnd_mode;

  mpc_get_struct (self_val, self)

  rb_scan_args (argc, argv, "03", &base_val, &sig_figs_val, &rnd_mode_val);
  base = rb_base_type_range_check (base_val);
  sig_figs = rb_sig_figs_type_range_check (sig_figs_val);
  if (NIL_P (rnd_mode_val)) { rnd_mode = r_mpc_default_rounding_mode; }
  else {                      rnd_mode = r_get_mpc_rounding_mode (rnd_mode_val); }

  str = mpc_get_str (base, sig_figs, self, rnd_mode);
  res_val = rb_str_new2 (str);

  mpc_free_str (str);
  return res_val;
}