/*
 *  $Id: math--inline.c 29427 2026-02-02 18:14:50Z yeti-dn $
 *  Copyright (C) 2003-2025 David Necas (Yeti), Petr Klapetek.
 *  E-mail: yeti@gwyddion.net, klapetek@gwyddion.net.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
 *  License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any
 *  later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along with this program; if not, write to the
 *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include <stdlib.h>

#include "libgwyddion/macros.h"
#include "libgwyddion/math.h"

/* In order to provide also linkable versions of the functions, kill the redirection macros and define the symbols.
 *
 * This is a separate source file to ensure everything else is compiled with the macros. */
#undef gwy_isnan
#undef gwy_isinf
#undef gwy_isnormal
#undef gwy_exp10
#undef gwy_sincos
#undef gwy_powi
#undef gwy_sinc
#undef gwy_deg2rad
#undef gwy_rad2deg

/**
 * gwy_exp10:
 * @x: Floating point number.
 *
 * Calculates the value of base-10 exponential function.
 *
 * This is an inline function or macro defined to a working exp10() implementation.
 **/
double
gwy_exp10(double x)
{
    return _gwy_exp10_implementation(x);
}

/**
 * gwy_sincos:
 * @x: Floating point number.
 * @sinval: Location for the sine of @x.
 * @cosval: Location for the cosine of @x.
 *
 * Calculates simultaneously the sine and cosine functions.
 *
 * This is an inline function or macro defined to a working sincos() implementation. If the system provides a sincos()
 * function, it is usually faster than separate sin() and cos() calls.
 **/
void
gwy_sincos(double x, double *sinval, double *cosval)
{
    _gwy_sincos_implementation(x, sinval, cosval);
}

/**
 * gwy_isnan:
 * @x: Floating point number.
 *
 * Alternative isnan() implementation which works even with GCC fast maths.
 *
 * Gwyddion is usually compiled to not rely on IEEE-compliant behaviour of infinities and NaNs (not-a-numbers) and
 * avoids such numbers. They are not normally allowed in Gwyddion files. If they occur in third-party files, the
 * standard treatment is to skip or mask them and replace the underlying data with neutral values (interpolation) as
 * necessary.
 *
 * One side-effect of using the faster, finite-only maths is that standard functions such as isnan() may not work.
 * They operate with NaNs by definition, and their behaviour is no longer well-defined. This prevents the detection of
 * NaNs needed to get rid of them. Hence, functions like gwy_isnan() exist to detect reliably abnormal values during
 * data import.
 **/
int
gwy_isnan(double x)
{
    return _gwy_isnan_implementation(x);
}

/**
 * gwy_isinf:
 * @x: Floating point number.
 *
 * Alternative isinf() implementation which works even with GCC fast maths.
 *
 * See gwy_isnan() for remarks.
 **/
int
gwy_isinf(double x)
{
    return _gwy_isinf_implementation(x);
}

/**
 * gwy_isnormal:
 * @x: Floating point number.
 *
 * Alternative isnormal() implementation which works even with GCC fast maths.
 **
 * See gwy_isnan() for remarks
 **/
int
gwy_isnormal(double x)
{
    return _gwy_isnormal_implementation(x);
}

/**
 * gwy_powi:
 * @x: Floating point number.
 * @i: Integer power.
 *
 * Calculates an integer power of a floating point number.
 *
 * This is an inline function or macro defined to a working integer power implementation. If the compiler provides
 * a builtin like GCC's __builtin_powi(), it is the implementation used.
 **/
double
gwy_powi(double x, int i)
{
    return _gwy_powi_implementation(x, i);
}

/**
 * gwy_sinc:
 * @x: Value to calculate sinc (cardinal sine) of.
 *
 * Calculates the sinc function.
 *
 * The sinc function is equal to sin(@x)/@x for non-zero @x, and defined to the limit 1 for zero @x.
 *
 * Returns: Value of sinc(@x).
 **/
gdouble
gwy_sinc(gdouble x)
{
    return _gwy_sinc_implementation(x);
}

/**
 * gwy_deg2rad:
 * @x: Angle in degrees.
 *
 * Converts an angle from degrees to radians.
 *
 * Returns: Value of @x in radians.
 **/
gdouble
gwy_deg2rad(gdouble x)
{
    return _gwy_deg2rad_implementation(x);
}

/**
 * gwy_rad2deg:
 * @x: Angle in radians.
 *
 * Converts an angle from radians to degrees.
 *
 * Returns: Value of @x in degrees.
 **/
gdouble
gwy_rad2deg(gdouble x)
{
    return _gwy_rad2deg_implementation(x);
}

/* vim: set cin columns=120 tw=118 et ts=4 sw=4 cino=>1s,e0,n0,f0,{0,}0,^0,\:1s,=0,g1s,h0,t0,+1s,c3,(0,u0 : */
