<?xml version="1.0" encoding="UTF-8"?>
<!--
 *
 * Scilab ( https://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2010 - 2011 - DIGITEO - Michael Baudin
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * This file is hereby licensed under the terms of the GNU GPL v2.0,
 * pursuant to article 5.3.4 of the CeCILL v.2.1.
 * This file was originally licensed under the terms of the CeCILL v2.1,
 * and continues to be available under such terms.
 * For more information, see the COPYING file which you should have received
 * along with this program.
 *
 -->
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="assert_comparecomplex" xml:lang="en">
    <refnamediv>
        <refname>assert_comparecomplex</refname>
        <refpurpose>Compare complex numbers with a tolerance.</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>
            order = assert_comparecomplex ( a , b )
            order = assert_comparecomplex ( a , b , reltol )
            order = assert_comparecomplex ( a , b , reltol , abstol )

        </synopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Parameters</title>
        <variablelist>
            <varlistentry>
                <term>a :</term>
                <listitem>
                    <para> a 1-by-1 matrix of doubles, the first value to be compared</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>b :</term>
                <listitem>
                    <para> a 1-by-1 matrix of doubles, the second value to be compared</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>reltol :</term>
                <listitem>
                    <para> a 1-by-1 matrix of doubles, the relative tolerance (default reltol=sqrt(%eps)).</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>abstol :</term>
                <listitem>
                    <para> a 1-by-1 matrix of doubles, the absolute tolerance (default abstol=0).</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>order :</term>
                <listitem>
                    <para> a 1-by-1 matrix of doubles, integer values,  the order. Returns order=0 is a is almost equal to b, order=-1 if a &lt; b, order=+1 if a &gt; b.</para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Description</title>
        <para>
            Compare first by real parts, then by imaginary parts.
            Takes into account numerical accuracy issues, by using
            a mixed relative and absolute tolerance criteria.
        </para>
        <para>
            Any optional input argument equal to the empty matrix is replaced by its default value.
        </para>
        <para>
            We use the following algorithm.
        </para>
        <para>
            We compare first the real parts. In case of tie, we compare the imaginary parts.
        </para>
        <para>
            We process the IEEE values and choose the order : -%inf &lt; 0 &lt; %inf &lt; %nan.
            If none of the values is special, we use the condition :
            <programlisting>
                cond = ( abs(a-b) &lt;= reltol * max(abs(a),abs(b)) + abstol )
            </programlisting>
        </para>
        <para>
            This algorithm is designed to be used into sorting
            algorithms.
            It allows to take into account for the portability issues
            related to the outputs of functions producing
            matrix of complex doubles.
            If this algorithm is plugged into a sorting function,
            it allows to consistently produce a sorted matrix,
            where the order can be independent of the operating system,
            the compiler or other forms of issues modifying the
            order (but not the values).
        </para>
        <para>
        </para>
    </refsection>
    <refsection>
        <title>Examples</title>
        <programlisting role="example"><![CDATA[
// Compare real values
assert_comparecomplex ( 1 , -1 ) // 1
assert_comparecomplex ( -1 , 1 ) // -1
assert_comparecomplex ( 1 , 1 ) // 0

// Compare complex values #1
assert_comparecomplex ( 1+2*%i , 1+3*%i ) // -1
assert_comparecomplex ( 1+3*%i , 1+2*%i ) // 1
assert_comparecomplex ( 1+2*%i , 1+2*%i ) // 0

// Compare complex values #2
assert_comparecomplex ( 1+%i , -1+%i ) // 1
assert_comparecomplex ( -1+%i , 1+%i ) // -1
assert_comparecomplex ( 1+%i , 1+%i ) // 0
[order,msg] = assert_comparecomplex ( 1+%i , 1+%i )

// Compare with tolerances : equality cases
assert_comparecomplex ( 1.2345+%i , 1.2346+%i , %eps , 1.e-3 ) // 0
assert_comparecomplex ( 1.2345+%i , 1.2346+%i , 1.e12*%eps , 0 ) // 0
assert_comparecomplex ( 1+1.2345*%i , 1+1.2347*%i , %eps , 1.e-3 ) // 0
assert_comparecomplex ( 1+1.2345*%i , 1+1.2347*%i , 1.e12*%eps , 0 ) // 0

// Compare more realistic data
x = [
-0.123452 - 0.123454 * %i
-0.123451 + 0.123453 * %i
0.123458 - 0.123459 * %i
0.123456 + 0.123457 * %i
];
// Consider less than 4 significant digits
for i = 1 : size(x,"*")-1
order = assert_comparecomplex ( x(i) , x(i+1) , 1.e-4 );
mprintf("compare(x(%d),x(%d))=%d\n",i,i+1,order)
end

// Compare data from bug #415
x = [
-1.9914145
-1.895889
-1.6923826
-1.4815461
-1.1302576
-0.5652256 - 0.0655080 * %i
-0.5652256 + 0.0655080 * %i
0.3354023 - 0.1602902 * %i
0.3354023 + 0.1602902 * %i
1.3468911
1.5040136
1.846668
1.9736772
1.9798866
];
// Consider less than 4 significant digits
for i = 1 : size(x,"*")-1
order = assert_comparecomplex ( x(i) , x(i+1) , 1.e-5 );
mprintf("compare(x(%d),x(%d))=%d\n",i,i+1,order)
end

   ]]></programlisting>
    </refsection>
    <refsection>
        <title>History</title>
        <revhistory>
            <revision>
                <revnumber>5.4.0</revnumber>
                <revdescription>Function introduced
                </revdescription>
            </revision>
        </revhistory>
    </refsection>
    <refsection>
        <title>Bibliography</title>
        <para>https://gitlab.com/scilab/scilab/-/blob/81a9cc049332de0c712cf56da585fcd25c8e59e3/scilab/modules/polynomials/tests/nonreg_tests/bug_415.tst</para>
        <para>https://gitlab.com/scilab/scilab/-/blob/4ce3d4109dd752fce5f763be71ea639e09a12630/scilab/modules/cacsd/tests/nonreg_tests/bug_68.tst</para>
    </refsection>
</refentry>
