# Imaginary Elementary Mathematical Functions - Very Low Priority

**URL:** <https://chapel.discourse.group/t/imaginary-elementary-mathematical-functions-very-low-priority/31022>\
**Category:** Users\
**Created:** [February 27, 2024, 6:27am UTC](https://chapel.discourse.group/t/imaginary-elementary-mathematical-functions-very-low-priority/31022 "2024-02-27T06:27:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)\
**Post date:** [February 27, 2024, 6:27am UTC](https://chapel.discourse.group/t/imaginary-elementary-mathematical-functions-very-low-priority/31022/1 "2024-02-27T06:27:39Z")

</div>

Chapel has not defined these (except for **abs** and **conj** ). These are vast simplifications of the **complex** (w) ones.That should be crafed at some stage.

This is a **very** , **very** low priority task but I thought I would note this while it is in my brain. Should I make it an issue? Relying on an implicit conversion of **imag** to **complex** condemns the user to significantly more computations.

Note that, given an **imag** (w) number `x`, and

```chapel
z = exp(x);

```

then `z.re == cos(x)` and `z.im == sin(x)`. The components should be computed with the same low overhead of the `sincos` routine seen in many C libraries.

---

<div class="post-metadata">

**Author:** ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)\
**Post date:** [February 27, 2024, 8:18am UTC](https://chapel.discourse.group/t/imaginary-elementary-mathematical-functions-very-low-priority/31022/2 "2024-02-27T08:18:16Z")

</div>

For that example quoted, one might have in `Math.chpl` something like the untested code:

```chapel
  inline proc exp :(x: imag(32)) {
    extern proc _chpl_exp_imag32(t:real(32)) : complex(64);
    return _chpl_exp_imag32(t);
  }

  inline proc exp :(x: imag(64)) {
    extern proc _chpl_exp_imag64(t:real(64)) : complex(128);
    return _chpl_exp_imag64(t);
  }

```

and in `chplmath.h`, a tweaked clone of Brad's code from `chpltypes.h`:

```chapel
static inline _complex128 _chpl_exp_imag64(_real64 t) {
// though CMPLX works for some C++ compilers, it doesn't work for all in our
// test environments, so dodge it to be safe; Currently, we only compile
// this header using a C++ compiler when compiling our re2 stubs, which
// don't seem to use this routine anyway.
  _real64 re, im;

  sincos(t, &im, &re);

#if defined(CMPLX) && !defined(__cplusplus)
  return CMPLX(re, im);
#else
#ifndef CHPL_DONT_USE_CMPLX_PTR_ALIASING
#define cmplx_re64(c) (((double *)&(c))[0])
#define cmplx_im64(c) (((double *)&(c))[1])
  _complex128 val;
  cmplx_re64(val) = re;
  cmplx_im64(val) = im;
  return val;
#else
  // This can generate bad values in the face of inf/nan values
  return re + im*_Complex_I;
#endif
#endif
}

static inline _complex64 _chpl_exp_imag32(_real32 t) {
// though CMPLXF works for some C++ compilers, it doesn't work for all in our
// test environments, so dodge it to be safe; Currently, we only compile
// this header using a C++ compiler when compiling our re2 stubs, which
// don't seem to use this routine anyway.
  _real32 re, im;

  sincos(t, &im, &re);

#if defined(CMPLXF) && !defined(__cplusplus)
  return CMPLXF(re, im);
#else
#ifndef CHPL_DONT_USE_CMPLX_PTR_ALIASING
#define cmplx_re32(c) (((float *)&(c))[0])
#define cmplx_im32(c) (((float *)&(c))[1])
  _complex64 val;
  cmplx_re32(val) = re;
  cmplx_im32(val) = im;
  return val;
#else
  // This can generate bad values in the face of inf/nan values
  return re + im*_Complex_I;
#endif
#endif
}

```

Something a little more complicated to throw at somebody like an intern would be the square root of an **imag** (w).

---

<div class="post-metadata">

**Author:** ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)\
**Post date:** [February 27, 2024, 11:54pm UTC](https://chapel.discourse.group/t/imaginary-elementary-mathematical-functions-very-low-priority/31022/3 "2024-02-27T23:54:53Z")

</div>

I thought I would just check that.

```chapel
inline proc sqrt(y : imag(?w))
{
        type Real = real(w);
        type Uint = uint(w);

        inline proc negativeBitTransfer(t : Real, s : Real)
        {
                const n = s.transmute(Uint) & (1:Uint << (w - 1));

                return (n | t.transmute(Uint)).transmute(Real);
        }
        param half = 0.5:Real;
        const realy = y:Real;
        const a = sqrt(abs(half * realy));
        const b = negativeBitTransfer(a, realy);

        return (a, b):complex(2 * w);
}

config const r = 36.0;

proc verify(const r : real(?w)) // compute complex square root and check errors
{
        const ups = (1 << (if w == 32 then 23 else 52)):real(w);
        const y = r:imag(w);
        const s = sqrt(y);

        writeln(' SQRT(y) = ', s);
        writeln('ERROR/EPS = ', ups * (s * s - y) / (if r == 0 then 1:real(w) else r));
}

proc main
{
        verify(r);
        verify(-r);
        verify(+0.0);
        verify(-0.0);
        exit(0);
}

```

**ALL GOOD**

---

<div class="post-metadata">

**Author:** ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)\
**Post date:** [February 28, 2024, 7:42am UTC](https://chapel.discourse.group/t/imaginary-elementary-mathematical-functions-very-low-priority/31022/4 "2024-02-28T07:42:03Z")

</div>

**ALL GOOD**

It always helps if there is no bug in the reference program.

---

<div class="post-metadata">

**Author:** ![mppf](https://avatars.discourse-cdn.com/v4/letter/m/94ad74/32.png) [@mppf](https://chapel.discourse.group/u/mppf)\
**Post date:** [February 29, 2024, 4:30pm UTC](https://chapel.discourse.group/t/imaginary-elementary-mathematical-functions-very-low-priority/31022/5 "2024-02-29T16:30:54Z")

</div>

Hi Damian -- It sounds like you have figured out the issue and everything is OK at this point.

I wanted to respond to just one thing

> [@damianmoz](#):
>
> This is a **very** , **very** low priority task but I thought I would note this while it is in my brain. Should I make it an issue?

Yes, making an issue is a good way to record something for future attention. It's more typical to look at / comment on old issues than to look at old Discourse posts. As a result, I think issues are more discoverable for people looking for a bug to fix and more likely to get comments from other users who are facing the same thing.

Of course, this is moot for this specific topic.
