* Bug 15028 fixed: assert_checkalmostequal() did not accept polynomials
[scilab.git] / scilab / modules / development_tools / help / en_US / assert / assert_checkalmostequal.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3  *
4  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
5  * Copyright (C) 2010 - 2011 - DIGITEO - Michael Baudin
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  -->
17 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
18           xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml"
19           xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"
20           xmlns:scilab="http://www.scilab.org" xml:id="assert_checkalmostequal" xml:lang="en">
21     <refnamediv>
22         <refname>assert_checkalmostequal</refname>
23         <refpurpose>Check that computed and expected are numerically close.</refpurpose>
24     </refnamediv>
25     <refsynopsisdiv>
26         <title>Syntax</title>
27         <synopsis>
28             flag = assert_checkalmostequal ( computed , expected )
29             flag = assert_checkalmostequal ( computed , expected , reltol )
30             flag = assert_checkalmostequal ( computed , expected , reltol , abstol )
31             flag = assert_checkalmostequal ( computed , expected , reltol , abstol , comptype )
32             [flag,errmsg] = assert_checkalmostequal ( ... )
33
34         </synopsis>
35     </refsynopsisdiv>
36     <refsection>
37         <title>Parameters</title>
38         <variablelist>
39             <varlistentry>
40                 <term>computed:</term>
41                 <listitem>
42                     <para>
43                       matrix or hypermatrix or sparse matrix of decimal real or complex numbers;
44                       or matrix or hypermatrix of polynomials with real or complex coefficients:
45                       the computed result.
46                     </para>
47                 </listitem>
48             </varlistentry>
49             <varlistentry>
50                 <term>expected :</term>
51                 <listitem>
52                     <para>
53                       matrix or hypermatrix or sparse matrix of decimal real or complex numbers;
54                       or matrix or hypermatrix of polynomials with real or complex coefficients:
55                       the expected result.
56                     </para>
57                   <para>
58                     If <literal>computed</literal> are polynomials, <literal>expected</literal>
59                     must be polynomials as well.
60                   </para>
61                 </listitem>
62             </varlistentry>
63             <varlistentry>
64                 <term>reltol :</term>
65                 <listitem>
66                     <para>real number: the relative tolerance (default reltol=sqrt(%eps)).</para>
67                 </listitem>
68             </varlistentry>
69             <varlistentry>
70                 <term>abstol :</term>
71                 <listitem>
72                     <para>real number: the absolute tolerance (default abstol=0).</para>
73                 </listitem>
74             </varlistentry>
75             <varlistentry>
76                 <term>comptype :</term>
77                 <listitem>
78                   <para>keyword <literal>"matrix"</literal> or <literal>"element"</literal>
79                     (default <literal>"element"</literal>). The comparison type.</para>
80                 </listitem>
81             </varlistentry>
82             <varlistentry>
83                 <term>flag :</term>
84                 <listitem>
85                   <para>
86                     <literal>%t</literal> if computed is close to expected; else <literal>%f</literal>.
87                   </para>
88                 </listitem>
89             </varlistentry>
90             <varlistentry>
91                 <term>errmsg :</term>
92                 <listitem>
93                     <para>
94                       Unique string: the error message. If flag==%t, then errormsg=="".
95                       If flag==%f, then errmsg contains the error message.
96                     </para>
97                 </listitem>
98             </varlistentry>
99         </variablelist>
100     </refsection>
101     <refsection>
102         <title>Description</title>
103         <para>
104             Performs silently if the two arrays of doubles or complex doubles, or the two arrays
105             of real or complex polynomials computed and expected are close.
106             The variables computed and expected can be exchanged without changing the result.
107         </para>
108         <para>
109           In case of polynomials, the size of both arrays, the degrees, and finally the
110           matrices of their coefficients are compared within the given or default tolerances.
111         </para>
112         <para>
113             Any optional input argument equal to the empty matrix is replaced by its default value.
114         </para>
115         <para>
116             We use the following algorithm.
117             We compare first the real parts. In case of equality, we compare the imaginary parts.
118         </para>
119         <para>
120             The condition used is mixed relative and absolute:
121             <programlisting>
122                 ( |e-c| &lt;= reltol * max(|e|,|c|) + abstol )
123             </programlisting>
124             If comptype="matrix", the norm is used.
125             If comptype="element", the absolute value are used and the two matrices are
126             almost equal if all the conditions are true.
127         </para>
128         <para>
129             The default value comptype="matrix" option performs the comparison for the matrices as a whole,
130             the norm of the difference of the matrices is used.
131             The comptype="element" option performs the comparison elementwise, i.e.
132             all the elements of the matrices must be almost equal.
133             Choosing between these two comparison types must be done with care.
134             For example, if we are checking the elementwise output of an elementary function,
135             we should choose the "element" comparison type, since we must compare the
136             matrix elements one after the other.
137         </para>
138         <para>
139             If the IEEE values %inf, -%inf or %nan values are in the matrices,
140             then they are almost equal only if the IEEE values are
141             at the same indices in the matrices.
142         </para>
143         <para>
144             The default comparison is based on a relative error, ensuring that 8 digits are common.
145             This allows to assert the number of significant digits in the computed result.
146         </para>
147         <para>
148             This procedure only works when the computed and expected variables
149             are matrices of doubles.
150             It will generate an error in any other case.
151         </para>
152         <para>
153             If the comparison shows that computed is not almost equal to expected,
154             <itemizedlist>
155                 <listitem>
156                     <para>if the errmsg output variable is not used, an error is generated,</para>
157                 </listitem>
158                 <listitem>
159                     <para>if the errmsg output variable is used, no error is generated.</para>
160                 </listitem>
161             </itemizedlist>
162         </para>
163         <para>
164             In the process of comparing the values, we separate %nan, +%inf, -%inf and remaining values.
165             Comparing nan values between them is not possible. This is why we compare the
166             indices where %nan value occurs.
167             If we form differences of infinity values, we produce %nan values.
168             This is why we compare the indices where +%inf values occurs.
169             We do the same for -%inf values.
170             Then, the non-nan, non-infinity values are actually compared.
171         </para>
172         <para>
173             The default comptype="element" option performs the comparison elementwise, i.e.
174             all the elements of the matrices must be almost equal.
175             The comptype="matrix" option performs the comparison for the matrices as a whole,
176             the norm of the difference of the matrices is used.
177         </para>
178         <para>
179             In general, the relative tolerance should be
180             set to a multiple of the machine precision %eps.
181             The relative tolerance should also be chosen with the lowest
182             possible magnitude, that is, we should configure
183             the tolerance as accurately as possible.
184             During the process of configuring the relative tolerance, we
185             suggest to use the following values, in that order :
186             0 (all digits correct), %eps, 10*%eps, 100*%eps, 1.e3*%eps, 1.e4*%eps, ...,
187             1.e17*%eps (no digit correct).
188             See below for examples of this.
189         </para>
190         <para>
191             This function takes into account for complex numbers.
192             We first compare the real parts of the input arguments.
193             If this fails, we immediately return.
194             If this succeeds, we compare the imaginary parts of the input arguments.
195         </para>
196         <para>
197         </para>
198     </refsection>
199     <refsection>
200         <title>Examples</title>
201         <programlisting role="example"><![CDATA[
202 // Comparisons which are successful.
203 // Relative error :
204 assert_checkalmostequal ( 1 , 1 );
205 assert_checkalmostequal ( 1 , 1 , %eps );
206 assert_checkalmostequal ( ones(10,1) , ones(10,1) , %eps );
207 // Absolute error :
208 assert_checkalmostequal ( 1.23456789123456789e-30 , 0 , 0 , 1.e-10 );
209 assert_checkalmostequal ( [1 %nan], [1 %nan] , 0 , %eps );
210
211 // Comparisons which are failures.
212 // Error message produced :
213 assert_checkalmostequal ( 1 , 2 , %eps );
214 // Error message produced :
215 flag = assert_checkalmostequal ( 1 , 2 , %eps )
216 // No error message produced :
217 [flag,errmsg] = assert_checkalmostequal ( 1 , 2 , %eps )
218 assert_checkalmostequal ( 1 , [2 3] , %eps );
219 assert_checkalmostequal ( [%nan 1], [1 %nan] , %eps );
220 assert_checkalmostequal ( 1 + 5 * %eps , 1 , %eps );
221 assert_checkalmostequal ( 1.23456789123456789e-30 , 1.3e-30 , %eps );
222
223 // In the case where expected is nonzero, the
224 // tolerance for relative error should be a
225 // multiple of %eps.
226 // The following test is a success and shows
227 // that less than 11 digits are lost with respect
228 // to the maximum possible accuracy.
229 assert_checkalmostequal ( 1.23456 , 1.23457 , 1.e11*%eps );
230
231 // We cannot exchange the relative and absolute tolerances.
232 // The following test pass: we use an absolute tolerance
233 // because the expected value is zero.
234 assert_checkalmostequal ( 1.23456789e-30 , 0 , 0 , 1.e-10 );
235 // The following test fail: we use a relative tolerance.
236 assert_checkalmostequal ( 0 , 1.23456789e-30 , 1.e-10 );
237
238 // We must configure the tolerance as tightly as possible.
239 // The following test fails, because the tolerance is too small
240 // with respect to the given numbers.
241 assert_checkalmostequal ( 1.23456 , 1.23457 , %eps );
242 // In order to get the number of common digits:
243 assert_computedigits(1.23456 , 1.23457)
244 // which returns 5.09...
245 // We now make a judgment on the accuracy and conclude it is acceptable:
246 assert_checkalmostequal ( 1.23456 , 1.23457 , 1.e-5 );
247
248 // We give here a practical example of the use of assert_checkalmostequal.
249 // We solve an averagely ill-conditionned system of linear
250 // equations, based on the Hilbert matrix.
251 n = 6;
252 // The expected value is set by ourselves.
253 expected = ones(n,1);
254 A = testmatrix("hilb",n);
255 // We compute the condition number of the matrix : ~10^8
256 ceil(log10(cond(A)))
257 // This means that the number of digits lost,
258 // predicted by theory, is 8.
259 // The right-hand side is computed given A and expected.
260 b = A * expected;
261 // In this case, a Gauss algorithm with partial
262 // pivoting is used.
263 computed = A\b;
264 // The following test fails: we have lost some digits.
265 assert_checkalmostequal(computed,expected,%eps)
266 // We compute the actual number of common digits: from 10 to 12
267 assert_computedigits(computed, expected)
268 // We accept this computation.
269 // The following test pass.
270 assert_checkalmostequal(computed,expected,1.e5*%eps);
271
272 // The following examples show the difference between comptype="element" and "matrix".
273 // The following test does not pass.
274 assert_checkalmostequal ( [1 1.e5] , [2 1.e5] , 1.e-3 )
275 // The following test pass with the matrix-based comparison.
276 assert_checkalmostequal ( [1 1.e5] , [2 1.e5] , 1.e-3 , [] , "matrix" )
277
278 // The following test pass.
279 // It is non-trivial to take into account for IEEE values.
280 [flag,errmsg] = assert_checkalmostequal ( [1.2345 %inf -%inf %nan] , [1.2346 %inf -%inf %nan] , 1.e-4 )
281
282 // This function takes into account for complex numbers.
283 // The following test pass.
284 assert_checkalmostequal ( 1+%i , 1+(1+1.e-4)*%i , 1.e-3 , [], "element" );
285 // The following test fails.
286 assert_checkalmostequal ( 1+%i , 1+(1+1.e-4)*%i , 1.e-5 , [], "element" );
287
288    ]]></programlisting>
289     </refsection>
290     <refsection>
291         <title>History</title>
292         <revhistory>
293             <revision>
294                 <revnumber>5.4.0</revnumber>
295                 <revdescription>
296                     Function introduced.
297                 </revdescription>
298             </revision>
299             <revision>
300                 <revnumber>6.0.1</revnumber>
301                 <revdescription>
302                     Extension to polynomials.
303                 </revdescription>
304             </revision>
305         </revhistory>
306     </refsection>
307 </refentry>