1 /* 2 * Copyright (c) 2004-2014, Bruno Levy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * * Neither the name of the ALICE Project-Team nor the names of its 14 * contributors may be used to endorse or promote products derived from this 15 * software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * If you modify this software, you should include a notice giving the 30 * name of the person performing the modification, the date of modification, 31 * and the reason for such modification. 32 * 33 * Contact: Bruno Levy 34 * 35 * Bruno.Levy@inria.fr 36 * http://www.loria.fr/~levy 37 * 38 * ALICE Project 39 * LORIA, INRIA Lorraine, 40 * Campus Scientifique, BP 239 41 * 54506 VANDOEUVRE LES NANCY CEDEX 42 * FRANCE 43 * 44 */ 45 46 #ifndef OPENNL_H 47 #define OPENNL_H 48 49 #include "nl_linkage.h" 50 #include <stdio.h> 51 52 #ifdef __cplusplus 53 extern "C" { 54 #endif 55 56 #define NL_VERSION_4_0 1 57 58 #define NLAPI 59 60 /* 61 * Deactivate warnings about documentation 62 * We do that, because CLANG's doxygen parser does not know 63 * some doxygen commands that we use (retval, copydoc) and 64 * generates many warnings for them... 65 */ 66 67 #if defined(__clang__) 68 #pragma clang diagnostic ignored "-Wunknown-pragmas" 69 #pragma clang diagnostic ignored "-Wdocumentation" 70 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" 71 #endif 72 73 /** 74 * \file geogram/NL/nl.h 75 * \brief The public API of the OpenNL linear solver library. 76 * Click the "More..." link below for simple example programs. 77 * \details 78 * The purpose of the example programs shown below is to demonstrate OpenNL 79 * programs that are as simple as possible. 80 * Note that for such small linear systems, the sparse iterative solvers in 81 * OpenNL will work, but they are completely inappropriate, one would normally 82 * solve the system directly. 83 * 84 * Example 1 (a simple linear system) 85 * ================================== 86 * Solve \f$ \left[ \begin{array}{ll} 1 & 2 \\ 3 & 4 \end{array} \right] 87 * \left[ \begin{array}{l} x \\ y \end{array} \right] 88 * = \left[ \begin{array}{l} 5 \\ 6 \end{array} \right] \f$ 89 * \code 90 * double x,y; // Solution of the system 91 * 92 * // Create and initialize OpenNL context 93 * nlNewContext(); 94 * nlSolverParameteri(NL_NB_VARIABLES, 2); 95 * 96 * // Build system 97 * nlBegin(NL_SYSTEM); 98 * nlBegin(NL_MATRIX); 99 * nlBegin(NL_ROW); 100 * nlCoefficient(0, 1.0); 101 * nlCoefficient(1, 2.0); 102 * nlRightHandSide(5.0); 103 * nlEnd(NL_ROW); 104 * nlBegin(NL_ROW); 105 * nlCoefficient(0, 3.0); 106 * nlCoefficient(1, 4.0); 107 * nlRightHandSide(6.0); 108 * nlEnd(NL_ROW); 109 * nlEnd(NL_MATRIX); 110 * nlEnd(NL_SYSTEM); 111 * 112 * // Solve and get solution 113 * nlSolve(); 114 * x = nlGetVariable(0); 115 * y = nlGetVariable(1); 116 * 117 * // Cleanup 118 * nlDeleteContext(nlGetCurrent()); 119 * \endcode 120 * 121 * Example 2 (least squares regression) 122 * ==================================== 123 * Reads \f$ (X,Y) \f$ coordinates from a file and finds the 124 * parameters \f$ a,b \f$ of the straight line \f$ y = ax + b \f$ 125 * that best fits the data points. 126 * \code 127 * FILE* input = fopen("datapoints.dat", "r"); 128 * double X,Y; // current datapoint 129 * 130 * // Create and initialize OpenNL context 131 * nlNewContext(); 132 * nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); 133 * nlSolverParameteri(NL_NB_VARIABLES, 2); 134 * 135 * // Build system 136 * nlBegin(NL_SYSTEM); 137 * nlBegin(NL_MATRIX); 138 * while(!feof(input)) { 139 * fread(input, "%f %f", &X, &Y); 140 * nlBegin(NL_ROW); 141 * nlCoefficient(0, X); 142 * nlCoefficient(1, 1.0); 143 * nlRightHandSide(Y); 144 * nlEnd(NL_ROW); 145 * } 146 * nlEnd(NL_MATRIX); 147 * nlEnd(NL_SYSTEM); 148 * 149 * // Solve and get solution 150 * nlSolve(); 151 * a = nlGetVariable(0); 152 * b = nlGetVariable(1); 153 * 154 * // Cleanup 155 * fclose(input); 156 * nlDeleteContext(nlGetCurrent()); 157 * \endcode 158 * 159 * Example 3 (least squares regression with locked variable) 160 * ========================================================= 161 * As in the previous example, reads \f$ (X,Y) \f$ coordinates from a 162 * file and finds the parameters \f$ a,b \f$ of the straight line \f$ y = ax + b \f$ 163 * that best fits the data points, but this time subject to the constraint \f$ a = 1 \f$. 164 * \code 165 * FILE* input = fopen("datapoints.dat", "r"); 166 * double X,Y; // current datapoint 167 * 168 * // Create and initialize OpenNL context 169 * nlNewContext(); 170 * nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); 171 * nlSolverParameteri(NL_NB_VARIABLES, 2); 172 * 173 * // Build system 174 * nlBegin(NL_SYSTEM); 175 * nlLockVariable(0); 176 * nlSetVariable(0, 1.0); 177 * nlBegin(NL_MATRIX); 178 * while(!feof(input)) { 179 * fread(input, "%f %f", &X, &Y); 180 * nlBegin(NL_ROW); 181 * nlCoefficient(0, X); 182 * nlCoefficient(1, 1.0); 183 * nlRightHandSide(Y); 184 * nlEnd(NL_ROW); 185 * } 186 * nlEnd(NL_MATRIX); 187 * nlEnd(NL_SYSTEM); 188 * 189 * // Solve and get solution 190 * nlSolve(); 191 * a = nlGetVariable(0); 192 * b = nlGetVariable(1); 193 * 194 * // Cleanup 195 * fclose(input); 196 * nlDeleteContext(nlGetCurrent()); 197 * \endcode 198 * 199 * Example 4 (fine tuning) 200 * ======================= 201 * Before calling nlBegin(NL_SYSTEM), if need be, it is possible to 202 * fine-tune additional parameters. See the following examples: 203 * 204 * \code 205 * nlSolverParameteri(NL_SOLVER, NL_GMRES); 206 * nlSolverParameteri(NL_MAX_ITERATIONS, 1000); 207 * nlSolverParameterd(NL_THRESHOLD, 1e-10); 208 * \endcode 209 * 210 */ 211 212 /** 213 * \name DataTypes and constants 214 * @{ 215 */ 216 217 /** 218 * \brief A symbolic constant. 219 */ 220 typedef unsigned int NLenum; 221 222 /** 223 * \brief A truth value (NL_TRUE or NL_FALSE). 224 * \see NL_TRUE, NL_FALSE 225 */ 226 typedef unsigned char NLboolean; 227 228 /** 229 * \brief A set of symbolic constants that can be 230 * combined with the bitwise or operator 231 */ 232 typedef unsigned int NLbitfield; 233 234 /** 235 * \brief Return type of functions that do not return 236 * a value. 237 */ 238 typedef void NLvoid; 239 240 /** 241 * \brief A 1-byte signed integer. 242 */ 243 typedef signed char NLbyte; 244 245 /** 246 * \brief A 2-bytes signed integer. 247 */ 248 typedef short NLshort; 249 250 /** 251 * \brief A 4-bytes signed integer. 252 */ 253 typedef int NLint; 254 255 /** 256 * \brief A 1-byte unsigned integer. 257 */ 258 typedef unsigned char NLubyte; 259 260 /** 261 * \brief A 2-bytes unsigned integer. 262 */ 263 typedef unsigned short NLushort; 264 265 /** 266 * \brief A 4-bytes unsigned integer. 267 */ 268 typedef unsigned int NLuint; 269 270 /** 271 * \brief A 8-bytes signed integer. 272 */ 273 typedef long NLlong; 274 275 /** 276 * \brief A 8-bytes unsigned integer. 277 */ 278 typedef unsigned long NLulong; 279 280 /** 281 * \brief Size of an object, 4-bytes signed integer. 282 */ 283 typedef int NLsizei; 284 285 /** 286 * \brief A single-precision floating-point number. 287 */ 288 typedef float NLfloat; 289 290 /** 291 * \brief A double-precision floating-point number. 292 */ 293 typedef double NLdouble; 294 295 /** 296 * \brief A function pointer. 297 * \see nlSetFunction(), nlGetFunction(), 298 * NL_FUNC_SOLVER, NL_FUNC_MATRIX, 299 * NL_FUNC_PRECONDITIONER, 300 * NL_FUNC_PROGRESS 301 */ 302 typedef void(*NLfunc)(void); 303 304 /** 305 * \brief An OpenNL context. 306 * \details OpenNL contexts should be considered as 307 * opaque ids. 308 * \see nlNewContext(), nlDeleteContext(), nlMakeCurrent(), nlGetCurrent() 309 */ 310 typedef void* NLContext; 311 312 /** 313 * \brief Constant for false \ref NLboolean%s. 314 * \see NLboolean 315 */ 316 #define NL_FALSE 0x0 317 /** 318 * \brief Constant for true \ref NLboolean%s. 319 * \see NLboolean 320 */ 321 #define NL_TRUE 0x1 322 323 /** 324 * @} 325 * \name Solver parameters 326 * @{ 327 */ 328 329 /** 330 * \brief Symbolic constant for nlSolverParameteri() to specify 331 * the used solver. 332 * \details Used as follows, before any call to nlBegin(): 333 * \code 334 * nlSolverParameteri(NL_SOLVER, solver); 335 * \endcode 336 * where solver is one of (\ref NL_CG, \ref NL_BICGSTAB, \ref NL_GMRES) 337 * or one of the extended solvers if supported 338 * (NL_xxx_SUPERLU_EXT, NL_CNC_xxx) or \ref NL_SOLVER_DEFAULT to 339 * let OpenNL decide and use a reasonable solver. 340 */ 341 #define NL_SOLVER 0x100 342 343 /** 344 * \brief Symbolic constant for nlSolverParameteri() to specify 345 * the number of variables. 346 * \details Used as follows, before any call to nlBegin(): 347 * \code 348 * nlSolverParameteri(NL_NB_VARIABLES, nb); 349 * \endcode 350 * where nb is the number of variables. 351 */ 352 #define NL_NB_VARIABLES 0x101 353 354 /** 355 * \brief Symbolic constant for nlSolverParameteri() to specify 356 * whether least squares mode is used. 357 * \details Used as follows, before any call to nlBegin(): 358 * \code 359 * nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); 360 * \endcode 361 * or 362 * \code 363 * nlSolverParameteri(NL_LEAST_SQUARES, NL_FALSE); 364 * \endcode 365 */ 366 #define NL_LEAST_SQUARES 0x102 367 368 /** 369 * \brief Symbolic constant for nlSolverParameteri() to specify 370 * the maximum number of iterations before the iterative solver 371 * is stopped. 372 * \details Usage: 373 * \code 374 * nlSolverParameteri(NL_MAX_ITERATIONS, nb); 375 * \endcode 376 * If the solver is left unspecified or is set to \ref NL_SOLVER_DEFAULT, 377 * then a reasonable maximum number of iterations is used (5 times the 378 * number of free variables). 379 */ 380 #define NL_MAX_ITERATIONS 0x103 381 382 /** 383 * \brief Symbolic constant for nlSolverParameterd() to specify 384 * the maximum threshold \f$ \| Ax - b \| / \| b \| \f$ before 385 * the iterative solver is stopped. 386 * \details Usage: 387 * \code 388 * nlSolverParameterd(NL_THRESHOLD, epsilon); 389 * \endcode 390 * If the solver is left unspecified or is set to 391 * \ref NL_SOLVER_DEFAULT, then a reasonable value is used (1e-6). 392 */ 393 #define NL_THRESHOLD 0x104 394 395 /** 396 * \brief Symbolic constant for nlSolverParameterd() to specify 397 * the relaxation parameter \f$ \omega \in (0,\ldots 2) \f$ used 398 * by the SSOR preconditioner. 399 * \details Usage: 400 * \code 401 * nlSolverParameterd(NL_OMEGA, omega) 402 * \endcode 403 * \see NL_PRECOND_SSOR 404 */ 405 #define NL_OMEGA 0x105 406 407 /** 408 * \brief Symbolic constant for nlSolverParameteri() to specify 409 * whether the constructed matrix is symmetric. 410 * \details If the constructed matrix is symmetric, pre-notifying 411 * OpenNL before constructing it may improve performance, by 412 * allowing more efficient data structures and solvers to be used. 413 * Usage: 414 * \code 415 * nlSolverParameteri(NL_SYMMETRIC, NL_TRUE); 416 * \endcode 417 * or 418 * \code 419 * nlSolverParameteri(NL_SYMMETRIC, NL_FALSE); 420 * \endcode 421 * \warning Behavior if undefined if setting \ref NL_SYMMETRIC 422 * and constructing a non-symmetric matrix afterwards. 423 */ 424 #define NL_SYMMETRIC 0x106 425 426 /** 427 * \brief Symbolic constant for nlGetIntegerv() to obtain the 428 * used number of iteration. 429 * \details The solver exits whenever the maximum number of 430 * iterations (\ref NL_MAX_ITERATIONS) is reached or whenever 431 * \f$ \| Ax - b \| / \| b \| \f$ gets smaller than \ref NL_THRESHOLD. 432 * Usage: 433 * \code 434 * NLint used_iter; 435 * nlGetIntegerv(NL_USED_ITERATIONS, &used_iter); 436 * \endcode 437 */ 438 #define NL_USED_ITERATIONS 0x107 439 440 /** 441 * \brief Symbolic constant for nlGetDoublev() to obtain the 442 * error after nlSolve() is called. 443 * \details Gets \f$ \| Ax - b \| / \| b \| \f$. 444 * Usage: 445 * \code 446 * NLdouble error; 447 * nlGetDoublev(NL_ERROR, &error); 448 * \endcode 449 */ 450 #define NL_ERROR 0x108 451 452 /** 453 * \brief Symbolic constant for nlSolverParameteri() to specify 454 * the number of iterations / number of stored vector in the 455 * inner \ref NL_GMRES loop. 456 * \details Only relevant if used solver is \ref NL_GMRES. 457 * Usage: 458 * \code 459 * nlSolverParameteri(NL_INNER_ITERATIONS, nn); 460 * \endcode 461 */ 462 #define NL_INNER_ITERATIONS 0x109 463 464 /** 465 * \brief Symbolic constant for nlGetDoublev() to obtain the 466 * time taken by the latest invocation of nlSolve(), in seconds. 467 * \details 468 * Usage: 469 * \code 470 * NLdouble seconds; 471 * nlGetDoublev(NL_ELAPSED_TIME, &seconds); 472 * \endcode 473 */ 474 #define NL_ELAPSED_TIME 0x10a 475 476 /** 477 * \brief Symbolic constant for nlSolverParameteri() to specify 478 * the used preconditioner. 479 * \details Should be one of 480 * (\ref NL_PRECOND_NONE, \ref NL_PRECOND_JACOBI, 481 \ref NL_PRECOND_SSOR, \ref NL_PRECOND_USER). 482 * If NL_PRECOND_USER is used, then the user-defined preconditioner is 483 * specified using nlSetFunction(). Usage: 484 * \code 485 * nlSolverParameteri(NL_PRECONDITIONER, NL_JACOBI); 486 * \endcode 487 */ 488 #define NL_PRECONDITIONER 0x10b 489 490 /** 491 * \brief Symbolic constant for nlGetDoublev() to obtain the 492 * average GFlop/Seconds performance counter during the latest 493 * invocation of nlSolve(). 494 * \details 495 * Usage: 496 * \code 497 * NLdouble gflops; 498 * nlGetDoublev(NL_GFLOPS, &gflops); 499 * \endcode 500 */ 501 #define NL_GFLOPS 0x10c 502 503 /** 504 * \brief Symbolic constant for nlGetIntegerv() to obtain the 505 * number of non-zero coefficient in the latest linear 506 * system used by nlSolve(). 507 * \details 508 * Usage: 509 * \code 510 * NLint nnz; 511 * nlGetIngerv(NL_NNZ, &nnz); 512 * \endcode 513 */ 514 #define NL_NNZ 0x10d 515 516 517 /** 518 * \brief Symbolic constant for nlSolverParameteri()/nlGetIntegerv() to 519 * define or query the number of linear systems to be solved. 520 */ 521 #define NL_NB_SYSTEMS 0x10e 522 523 /** 524 * @} 525 * \name Solvers 526 * @{ 527 */ 528 529 /** 530 * \brief Symbolic constant for nlSolverParameteri() 531 * to specify that OpenNL should automatically select a reasonable 532 * solver and preconditioner. 533 * \details It is the default operating mode of 534 * OpenNL. It can also be reset as follows: 535 * \code 536 * nlSolverParameteri(NL_SOLVER,NL_SOLVER_DEFAULT); 537 * \endcode 538 * It also lets OpenNL choose (hopefully reasonable) values for maximum number of iterations 539 * (\ref NL_MAX_ITERATIONS) = 5 times the number of free variables and 540 * threshold (\ref NL_THRESHOLD) = 1e-6. It uses the Jacobi-preconditioned 541 * conjugate gradient solver (\ref NL_CG and \ref NL_PRECOND_JACOBI) if the 542 * matrix is known to be symmetric, and \ref NL_BICGSTAB otherwise. 543 */ 544 #define NL_SOLVER_DEFAULT 0x000 545 546 /** 547 * \brief Symbolic constant for nlSolverParameteri() 548 * to select the Conjugate Gradient solver. 549 * \details Usage: 550 * \code 551 * nlSolverParameteri(NL_SOLVER, NL_CG); 552 * \endcode 553 * \warning The Conjugate Gradient solver requires the matrix to be 554 * symmetric (note that it is always the case in least-squares mode, 555 * but NOT in regular mode). 556 */ 557 #define NL_CG 0x200 558 559 /** 560 * \brief Symbolic constant for nlSolverParameteri() 561 * to select the Conjugate Gradient solver. 562 * \details Usage: 563 * \code 564 * nlSolverParameteri(NL_SOLVER, NL_BICGSTAB); 565 * \endcode 566 * \ref BICGSTAB works for both non-symmetric and symmetric matrices. 567 * If the matrix is known to be symmetric, then \ref CG will be more 568 * efficient. 569 */ 570 #define NL_BICGSTAB 0x201 571 572 /** 573 * \brief Symbolic constant for nlSolverParameteri() 574 * to select the GMRES solver. 575 * \details Usage: 576 * \code 577 * nlSolverParameteri(NL_SOLVER, NL_GMRES); 578 * \endcode 579 * GMRES works for both non-symmetric and symmetric matrices. 580 * If the matrix is known to be symmetric, then \ref NL_CG will be more 581 * efficient. GMRES has an additional internal number of iterations 582 * parameters that can be set as follows: 583 * \code 584 * nlSolverParameteri(NL_INNER_ITERATIONS,nn); 585 * \endcode 586 */ 587 #define NL_GMRES 0x202 588 589 /** 590 * @} 591 * \name Preconditioners 592 * @{ 593 */ 594 595 /** 596 * \brief Symbolic constant for nlSolverParameteri() 597 * to use no preconditioner. 598 * \details Usage: 599 * \code 600 * nlSolverParameteri(NL_PRECONDITIONER, NL_PRECOND_NONE); 601 * \endcode 602 */ 603 #define NL_PRECOND_NONE 0x000 604 605 /** 606 * \brief Symbolic constant for nlSolverParameteri() 607 * to use the Jacobi preconditioner. 608 * \details The Jacobi preconditioner corresponds to the 609 * inverse of the diagonal elements. Clearly, it requires 610 * that the matrix has no zero element on the diagonal. 611 * Usage: 612 * \code 613 * nlSolverParameteri(NL_PRECONDITIONER, NL_PRECOND_JACOBI); 614 * \endcode 615 */ 616 #define NL_PRECOND_JACOBI 0x300 617 618 /** 619 * \brief Symbolic constant for nlSolverParameteri() 620 * to use the SSOR (Successive Over Relaxation) preconditioner. 621 * \details 622 * Usage: 623 * \code 624 * nlSolverParameteri(NL_PRECONDITIONER, NL_PRECOND_SSOR); 625 * \endcode 626 * The SSOR preconditioner can significantly reduce the number 627 * of used iterations, but each iteration takes much longer. 628 * It has an additional Omega parameter: 629 * \see NL_OMEGA 630 */ 631 #define NL_PRECOND_SSOR 0x301 632 633 /** 634 * \brief Symbolic constant for nlSolverParameteri() 635 * to use a user-defined preconditioner. 636 * \details 637 * Usage: 638 * \code 639 * nlSolverParameteri(NL_PRECONDITIONER, NL_PRECOND_USER); 640 * \endcode 641 * The user-defined preconditoner is specified as a function 642 * pointer, \see nlSetFunction(), NL_FUNC_PRECONDITIONER, NL_PRECONDITIONER 643 */ 644 #define NL_PRECOND_USER 0x303 645 646 /** 647 * @} 648 * \name Enable / Disable 649 * @{ 650 */ 651 652 /** 653 * \brief Symbolic constant for nlEnable() / nlDisable() 654 * to enable or disable rows normalization. 655 * \details When row normalization is enabled, each time 656 * a row is completed with nlEnd(NL_ROW), the 657 * coefficients of the current row and its right hand 658 * side are divided by the length \f$ L \f$ of the current row 659 * (and multiplied by the \ref NL_ROW_SCALING \f$ s \f$ if one 660 * was specified): 661 * \f[ 662 * \begin{array}{lcl} 663 * L & \leftarrow & \sqrt{\sum_{j} a_{i,j}^2} \\ 664 * a_{i,j} & \leftarrow & a_{i,j} \times s / L \\ 665 * b_i & \leftarrow & b_i \times s / L 666 * \end{array} 667 * \f] 668 * Usage: 669 * \code 670 * nlEnable(NL_NORMALIZE_ROWS); 671 * \endcode 672 * or 673 * \code 674 * nlDisable(NL_NORMALIZE_ROWS); 675 * \endcode 676 * \see nlEnable(), nlDisable(), nlIsEnabled(), NL_ROW_SCALING 677 */ 678 #define NL_NORMALIZE_ROWS 0x400 679 680 /** 681 * \brief Symbolic constant for nlEnable() / nlDisable() 682 * to enable or disable messages. 683 * \details Usage: 684 * \code 685 * nlEnable(NL_VERBOSE) 686 * \endcode 687 * or 688 * \code 689 * nlDisable(NL_VERBOSE) 690 * \endcode 691 * \see nlEnable(), nlDisable(), nlIsEnabled() 692 */ 693 #define NL_VERBOSE 0x401 694 695 696 /** 697 * \brief Symbolic constant for nlEnable() / nlDisable() 698 * to enable or disable variables indirection. 699 * \details Usage: 700 * \code 701 * nlEnable(NL_NO_VARIABLES_INDIRECTION) 702 * \endcode 703 * or 704 * \code 705 * nlDisable(NL_NO_VARIABLES_INDIRECTION) 706 * \endcode 707 * \see nlEnable(), nlDisable(), nlIsEnabled() 708 */ 709 #define NL_NO_VARIABLES_INDIRECTION 0x402 710 711 /** 712 * @} 713 * \name Context management 714 * @{ 715 */ 716 717 /** 718 * \brief Creates a new OpenNL context 719 * \details Must be called before any other OpenNL function. 720 * On exit, the newly created context is the current OpenNL 721 * context. Several OpenNL context may coexist. All OpenNL calls are 722 * forwarded to the current OpenNL context. Use nlMakeCurrent() 723 * to switch between multiple OpenNL contexts. 724 * Any created context needs to be destroyed before the end 725 * of the program using nlDeleteContext(). 726 * \return a handle to the newly created context. 727 */ 728 NLAPI NLContext NLAPIENTRY nlNewContext(void); 729 730 /** 731 * \brief Destroys an existing OpenNL context 732 * \details This deallocates all the memory used by the context. 733 * \param[in,out] context the context to be destroyed 734 */ 735 NLAPI void NLAPIENTRY nlDeleteContext(NLContext context); 736 737 /** 738 * \brief Sets the current OpenNL context. 739 * \details If several OpenNL contexts need to be used simultaneously, 740 * this function can be used to redirect all OpenNL calls to a specific 741 * context. 742 */ 743 NLAPI void NLAPIENTRY nlMakeCurrent(NLContext context); 744 745 /** 746 * \brief Gets the current context 747 * \return a handle to the current OpenNL context 748 */ 749 NLAPI NLContext NLAPIENTRY nlGetCurrent(void); 750 751 /** 752 * \brief Initializes an OpenNL extension 753 * \details OpenNL may be compiled with several extensions, that provide 754 * alternative solvers, such as SuperLU (sparse direct solver) and CNC 755 * (iterative solver on the GPU). This function tests whether an extension 756 * is supported, and initializes what needs to be initialized in the extention. 757 * \retval NL_TRUE if the extension is supported and could be successfully 758 * initialized 759 * \retval NL_FALSE otherwise 760 */ 761 NLAPI NLboolean NLAPIENTRY nlInitExtension(const char* extension); 762 763 /** 764 * \brief Tests whether an OpenNL extension is initialized. 765 * \retval NL_TRUE if the extension is initialized. 766 * \retval NL_FALSE otherwise 767 */ 768 NLAPI NLboolean NLAPIENTRY nlExtensionIsInitialized(const char* extension); 769 770 /** 771 * \brief Initializes OpenNL using command line arguments. 772 * \details Command line arguments of the form nl:<extension>=true|false are parsed 773 * and taken into account. Calling this function is not mandatory. 774 */ 775 NLAPI void NLAPIENTRY nlInitialize(int argc, char** argv); 776 777 /** 778 * @} 779 * \name State Get/Set 780 * @{ 781 */ 782 783 /** 784 * \brief Specifies a floating-point solver parameter 785 * \details This function should be called in the initial state of OpenNL, 786 * before any nlBegin() / nlEnd() call. 787 * \param[in] pname the symbolic name of the parameter, 788 * one of (\ref NL_THRESHOLD, \ref NL_OMEGA). 789 * \param[in] param the double-precision floating-point value of the parameter. 790 * \arg \p If pname = \ref NL_THRESHOLD, then \p param is the maximum value of 791 * \f$ \| Ax - b \| / \| b \| \f$ before iterations are stopped; 792 * \arg \p if pname = \ref NL_OMEGA and the specified preconditioner 793 * is \ref NL_SSOR, then \p param is the relaxation parameter, 794 * in (0.0 .. 2.0) excluded, for the SSOR preconditioner. 795 */ 796 NLAPI void NLAPIENTRY nlSolverParameterd(NLenum pname, NLdouble param); 797 798 /** 799 * \brief Specifies an integer solver parameter 800 * \details This function should be called in the initial state of OpenNL, 801 * before any nlBegin() / nlEnd() call. 802 * \param[in] pname the symbolic name of the parameter, one of 803 * (\ref NL_SOLVER, \ref NL_NB_VARIABLES, \ref NL_LEAST_SQUARES, 804 * \ref NL_MAX_ITERATIONS, \ref NL_SYMMETRIC, \ref NL_INNER_ITERATIONS, 805 * \ref NL_PRECONDITIONER). 806 * \param[in] param the integer value of the parameter. 807 * \arg If \p pname = \ref NL_SOLVER then \p param is the symbolic 808 * constant that specifies the solver, i.e. one of (NL_CG, NL_BICGSTAB, NL_GMRES) 809 * or one of the extended solvers if supported (NL_xxx_SUPERLU_EXT, NL_CNC_xxx); 810 * \arg if \p pname = \ref NL_NB_VARIABLES then \p param specifies the number of variables; 811 * \arg if \p pname = \ref NL_LEAST_SQUARES then \p param is a boolean value 812 * (NL_TRUE or NL_FALSE) that specifies whether least squares mode should be 813 * used (solves \f$ A^t A x = A^t b \f$ with a possibly non-square matrix \f$ A \f$); 814 * \arg if \p pname = \ref NL_MAX_ITERATIONS then \p param is the maximum number of iterations; 815 * \arg if \p pname = \ref NL_SYMMETRIC then \p param is a boolean value (NL_TRUE or NL_FALSE) that 816 * specifies whether the constructed matrix is symmetric. This is a hint for OpenNL 817 * that allows using more efficient data structures / solvers. Behavior is undefined 818 * if you lied and specify then a non-symmetric matrix ! 819 * \arg if \p pname = \ref NL_INNER_ITERATIONS and the solver is NL_GMRES, 820 * then \p param is the number of inner-loop iterations / 821 * number of intermediate vectors used by GMRES; 822 * \arg if \p pname = \ref NL_PRECONDITIONER then \p param is the 823 * symbolic constant that specifies the preconditioner, i.e. one of 824 * (\ref NL_PRECOND_NONE, \ref NL_PRECOND_JACOBI, \ref NL_PRECOND_SSOR). 825 * 826 * \see NL_SOLVER, NL_NB_VARIABLES, NL_LEAST_SQUARES, NL_MAX_ITERATIONS, 827 * NL_SYMMETRIC, NL_INNER_ITERATIONS, NL_PRECONDITIONER 828 */ 829 NLAPI void NLAPIENTRY nlSolverParameteri(NLenum pname, NLint param); 830 831 /** 832 * \brief Gets the value of a boolean parameter 833 * \param[in] pname the symbolic name of the parameter 834 * \param[out] params a pointer to the obtained parameter value 835 */ 836 NLAPI void NLAPIENTRY nlGetBooleanv(NLenum pname, NLboolean* params); 837 838 /** 839 * \brief Gets the value of a double-precision floating-point parameter 840 * \param[in] pname the symbolic name of the parameter 841 * \param[out] params a pointer to the obtained parameter value 842 */ 843 NLAPI void NLAPIENTRY nlGetDoublev(NLenum pname, NLdouble* params); 844 845 /** 846 * \brief Gets the value of an integer parameter 847 * \param[in] pname the symbolic name of the parameter 848 * \param[out] params a pointer to the obtained parameter value 849 */ 850 NLAPI void NLAPIENTRY nlGetIntegerv(NLenum pname, NLint* params); 851 852 /** 853 * \brief Gets the value of a 64 bits integer parameter 854 * \param[in] pname the symbolic name of the parameter 855 * \param[out] params a pointer to the obtained parameter value 856 */ 857 NLAPI void NLAPIENTRY nlGetIntegervL(NLenum pname, NLlong* params); 858 859 860 /** 861 * \brief Sets a boolean parameter to NL_TRUE 862 * \param[in] pname the symbolic name of the parameter 863 */ 864 NLAPI void NLAPIENTRY nlEnable(NLenum pname); 865 866 /** 867 * \brief Sets a boolean parameter to NL_FALSE 868 * \param[in] pname the symbolic name of the parameter 869 */ 870 NLAPI void NLAPIENTRY nlDisable(NLenum pname); 871 872 /** 873 * \brief Tests a boolean parameter 874 * \param[in] pname the symbolic name of the parameter 875 * \return the value of the boolean parameter 876 */ 877 NLAPI NLboolean nlIsEnabled(NLenum pname); 878 879 /** 880 * @} 881 * \name Function pointers 882 * @{ 883 */ 884 885 /** 886 * \brief Symbolic constant for nlSetFunction(), used 887 * to replace OpenNL solver with a user-defined routine. 888 * \details 889 * \note For advanced users only, requires to dig into 890 * OpenNL internal structures. 891 * \code 892 * #include <nl_context.h> 893 * NLboolean my_solver() { 894 * NLContextStruct* context = (NLContextStruct*)nlGetCurrent(); 895 * ... 896 * ... 897 * } 898 * nlSetFunction(NL_FUNC_SOLVER, (nlFunc)my_solver); 899 * \endcode 900 */ 901 #define NL_FUNC_SOLVER 0x600 902 903 /** 904 * \brief Symbolic constant for nlSetFunction(), used 905 * to replace OpenNL matrix-vector product with a 906 * user-defined routine. 907 * \details 908 * \code 909 * void my_matrix_func(const double* x, double* y) { 910 * ... 911 * } 912 * nlSetFunction(NL_FUNC_MATRIX, (nlFunc)my_matrix_func); 913 * \endcode 914 */ 915 #define NL_FUNC_MATRIX 0x601 916 917 /** 918 * \brief Symbolic constant for nlSetFunction(), used 919 * to replace OpenNL preconditioner with a user-defined routine. 920 * \details 921 * \code 922 * void my_precond_func(const double* x, double* y) { 923 * ... 924 * } 925 * nlSolverParameteri(NL_PRECONDITIONER, NL_PRECOND_USER); 926 * nlSetFunction(NL_FUNC_PRECONDITIONER, (nlFunc)my_precond_func); 927 * \endcode 928 * \see nlSetFunction(), NL_PRECONDITIONER 929 */ 930 #define NL_FUNC_PRECONDITIONER 0x602 931 932 /** 933 * \brief Symbolic constant for nlSetFunction(), used 934 * to display a progress bar during solve, using a 935 * user-defined callback. 936 * \details The user-defined progress callback is called 937 * after each iteration, and can be used to update a 938 * progress bar. 939 * \code 940 * void my_progress_callback( 941 * NLuint cur_iter, // Current iteration 942 * NLuint max_iter, // Maximum number of iterations 943 * double cur_err, // Current (squared, un-normalized) error 944 * double max_err // Maximum (squared, un-normalized) error 945 * ) { 946 * ... 947 * } 948 * nlSetFunction(NL_FUNC_PROGRESS, (nlFunc)my_progress_callback); 949 * \endcode 950 */ 951 #define NL_FUNC_PROGRESS 0x603 952 953 /** 954 * \brief Sets a function pointer 955 * \param[in] pname symbolic name of the function, one of (\ref NL_FUNC_MATRIX, 956 * \ref NL_FUNC_PRECONDITIONER, \ref NL_FUNC_PROGRESS) 957 * \param[in] param the function pointer 958 * \see nlGetFunction(), NL_FUNC_MATRIX, NL_FUNC_PRECONDITIONER, 959 * NL_FUNC_PROGRESS 960 */ 961 NLAPI void NLAPIENTRY nlSetFunction(NLenum pname, NLfunc param); 962 963 /** 964 * \brief Gets a function pointer 965 * \param[in] pname symbolic name of the function 966 * \param[out] param the function pointer 967 * \see nlSetFunction(), NL_FUNC_MATRIX, NL_FUNC_PRECONDITIONER, 968 * NL_FUNC_PROGRESS 969 */ 970 NLAPI void NLAPIENTRY nlGetFunction(NLenum pname, NLfunc* param); 971 972 /** 973 * @} 974 * \name Variables 975 * @{ 976 */ 977 978 /** 979 * \brief Sets the value of a variable 980 * \param[in] i index of the variable, between 0 and 981 * nlGetInteger(NL_NB_VARIABLES)-1 982 * \param[in] value value of the variable 983 * \see nlGetVariable(), nlLockVariable(), nlUnlockVariable(), 984 * nlVariableIsLocked() 985 */ 986 NLAPI void NLAPIENTRY nlSetVariable(NLuint i, NLdouble value); 987 988 989 /** 990 * \brief Sets the value of a variable when there are several systems 991 * to solve 992 * \param[in] i index of the variable, between 0 and 993 * nlGetInteger(NL_NB_VARIABLES)-1 994 * \param[in] k index of the system, between 0 and 995 * nlGetInteger(NL_NB_SYSTEMS)-1 996 * \param[in] value value of the variable 997 * \see nlMultiGetVariable() 998 */ 999 NLAPI void NLAPIENTRY nlMultiSetVariable( 1000 NLuint i, NLuint k, NLdouble value 1001 ); 1002 1003 /** 1004 * \brief Gets the value of a variable 1005 * \param[in] i index of the variable, between 0 and 1006 * nlGetInteger(NL_NB_VARIABLES)-1 1007 * \return the value of the variable 1008 * \see nlSetVariable(), nlLockVariable(), nlUnlockVariable(), 1009 * nlVariableIsLocked() 1010 */ 1011 NLAPI NLdouble NLAPIENTRY nlGetVariable(NLuint i); 1012 1013 /** 1014 * \brief Gets the value of a variable when there are several systems 1015 * to solve 1016 * \param[in] i index of the variable, between 0 and 1017 * nlGetInteger(NL_NB_VARIABLES)-1 1018 * \param[in] k index of the system, between 0 and 1019 * nlGetInteger(NL_NB_SYSTEMS)-1 1020 * \return value value of the variable 1021 * \see nlMultiSetVariable() 1022 */ 1023 NLAPI NLdouble NLAPIENTRY nlMultiGetVariable(NLuint i, NLuint k); 1024 1025 /** 1026 * \brief Locks a variable 1027 * \details Locked variables are no-longer computed by OpenNL, their initial 1028 * value, specified by nlSetVariable(), is used as follows: 1029 * - in standard mode, locked variables are moved to the right hand side 1030 * - in least squares mode, locked variables are removed from the degrees 1031 * of freedom and combined into the right hand side 1032 * \param[in] index index of the variable, between 0 and 1033 * nlGetInteger(NL_NB_VARIABLES)-1 1034 * \see nlGetVariable(), nlSetVariable(), nlUnlockVariable(), 1035 * nlVariableIsLocked() 1036 */ 1037 NLAPI void NLAPIENTRY nlLockVariable(NLuint index); 1038 1039 /** 1040 * \brief Unlocks a variable 1041 * \details Locked variables are no-longer computed by OpenNL, their initial 1042 * value, specified by nlSetVariable(), is used as follows: 1043 * - in standard mode, locked variables are moved to the right hand side 1044 * - in least squares mode, locked variables are removed from the degrees 1045 * of freedom and combined into the right hand side 1046 * \param[in] index index of the variable, between 0 and 1047 * nlGetInteger(NL_NB_VARIABLES)-1 1048 * \see nlGetVariable(), nlSetVariable(), nlLockVariable(), nlVariableIsLocked() 1049 */ 1050 NLAPI void NLAPIENTRY nlUnlockVariable(NLuint index); 1051 1052 /** 1053 * \brief Tests whether a variable is locked 1054 * \details Locked variables are no-longer computed by OpenNL, their initial 1055 * value, specified by nlSetVariable(), is used as follows: 1056 * - in standard mode, locked variables are moved to the right hand side 1057 * - in least squares mode, locked variables are removed from the degrees 1058 * of freedom and combined into the right hand side 1059 * \param[in] index index of the variable, between 0 and 1060 * nlGetInteger(NL_NB_VARIABLES)-1 1061 * \see nlGetVariable(), nlSetVariable(), nlLockVariable(), nlUnlockVariable() 1062 */ 1063 NLAPI NLboolean NLAPIENTRY nlVariableIsLocked(NLuint index); 1064 1065 /** 1066 * @} 1067 * \name Begin/End 1068 * @{ 1069 */ 1070 1071 /** 1072 * \brief Symbolic constant for nlBegin() / nlEnd(), to 1073 * be used to start creating / finalizing a linear system. 1074 * \details 1075 * \see nlBegin(), nlEnd() 1076 */ 1077 #define NL_SYSTEM 0x0 1078 1079 /** 1080 * \brief Symbolic constant for nlBegin() / nlEnd(), to 1081 * be used to start creating / finalizing a matrix. 1082 * \details 1083 * \see nlBegin(), nlEnd() 1084 */ 1085 #define NL_MATRIX 0x1 1086 1087 /** 1088 * \brief Symbolic constant for nlBegin() / nlEnd(), to 1089 * be used to start creating / finalizing a row. 1090 * \details 1091 * \see nlBegin(), nlEnd() 1092 */ 1093 #define NL_ROW 0x2 1094 1095 /** 1096 * \brief Symbolic constant for nlBegin() / nlEnd(), to 1097 * be used to start creating / finalizing a row. 1098 * \details 1099 * \see nlBegin(), nlEnd() 1100 */ 1101 #define NL_MATRIX_PATTERN 0x3 1102 1103 /** 1104 * \brief Begins a new primitive 1105 * \details nlBegin() / nlEnd() calls should be properly nested, as 1106 * follows (otherwise an assertion failure is triggered): 1107 * \code 1108 * nlBegin(NL_SYSTEM) 1109 * nlBegin(NL_MATRIX) 1110 * nlBegin(NL_ROW) 1111 * nlEnd(NL_ROW) 1112 * ... 1113 * nlBegin(NL_ROW) 1114 * nlEnd(NL_ROW) 1115 * nlEnd(NL_MATRIX) 1116 * nlEnd(NL_SYSTEM) 1117 * \endcode 1118 * \param[in] primitive one of NL_SYSTEM, NL_MATRIX, NL_ROW 1119 */ 1120 NLAPI void NLAPIENTRY nlBegin(NLenum primitive); 1121 1122 /** 1123 * \brief Begins a new primitive 1124 * \details nlBegin()/nlEnd() calls should be properly nested, as 1125 * follows (otherwise an assertion failure is triggered): 1126 * \code 1127 * nlBegin(NL_SYSTEM) 1128 * nlBegin(NL_MATRIX) 1129 * nlBegin(NL_ROW) 1130 * nlEnd(NL_ROW) 1131 * ... 1132 * nlBegin(NL_ROW) 1133 * nlEnd(NL_ROW) 1134 * nlEnd(NL_MATRIX) 1135 * nlEnd(NL_SYSTEM) 1136 * \endcode 1137 * \param[in] primitive one of NL_SYSTEM, NL_MATRIX, NL_ROW 1138 */ 1139 NLAPI void NLAPIENTRY nlEnd(NLenum primitive); 1140 1141 1142 /** 1143 * \brief Specifies the length of a row of the matrix. 1144 * \details Should be called between nlBegin(NL_MATRIX_PATTERN) and 1145 * nlEnd(NL_MATRIX_PATTERN). 1146 * \param[in] i the index of the row. 1147 * \param[in] n the length of the row. 1148 */ 1149 NLAPI void NLAPIENTRY nlSetRowLength(NLuint i, NLuint n); 1150 1151 /** 1152 * \brief Appends a coefficient to the current row. 1153 * \details This function should be called between a 1154 * nlBegin(NL_ROW) / nlEnd(NL_ROW) pair (else an assertion failure 1155 * is triggered). The coefficient is either accumumated into the matrix or 1156 * into the right-hand side according to the locked/unlocked status 1157 * of the variable. 1158 * \param[in] i index of the variable this coefficient is related with 1159 * \param[in] value value of the coefficient 1160 * \see nlBegin(), nlEnd(), NL_ROW, NL_RIGHT_HAND_SIDE, NL_ROW_SCALING, 1161 * NL_NORMALIZE_ROWS 1162 */ 1163 NLAPI void NLAPIENTRY nlCoefficient(NLuint i, NLdouble value); 1164 1165 1166 1167 /** 1168 * \brief Adds a coefficient to the current matrix. 1169 * \details This function should be called between a 1170 * nlBegin(NL_MATRIX) / nlEnd(NL_MATRIX) pair (else an assertion failure 1171 * is triggered). This function should not be called in least squares mode. 1172 * There should not be any locked variable when using this function. 1173 * \param[in] i , j indices 1174 * \param[in] value value to be added to the coefficient 1175 */ 1176 NLAPI void NLAPIENTRY nlAddIJCoefficient( 1177 NLuint i, NLuint j, NLdouble value 1178 ); 1179 1180 1181 /** 1182 * \brief Adds a coefficient to a component of the right hand side 1183 * of the equation. 1184 * \details This function should be called between a 1185 * nlBegin(NL_MATRIX) / nlEnd(NL_MATRIX) pair (else an assertion failure 1186 * is triggered). This function should not be called in least squares mode. 1187 * There should not be any locked variable when using this function. 1188 * \param[in] i index of the component 1189 * \param[in] value value to be added to the component 1190 */ 1191 NLAPI void NLAPIENTRY nlAddIRightHandSide(NLuint i, NLdouble value); 1192 1193 /** 1194 * \brief Adds a coefficient to a component of the right hand side 1195 * of the equation. 1196 * \details This function should be called between a 1197 * nlBegin(NL_MATRIX) / nlEnd(NL_MATRIX) pair (else an assertion failure 1198 * is triggered). This function should not be called in least squares mode. 1199 * There should not be any locked variable when using this function. 1200 * \param[in] i index of the component 1201 * \param[in] k index of the system 1202 * \param[in] value value to be added to the component 1203 */ 1204 NLAPI void NLAPIENTRY nlMultiAddIRightHandSide( 1205 NLuint i, NLuint k, NLdouble value 1206 ); 1207 1208 /** 1209 * \brief Sets the right-hand side of the current row. 1210 * \details 1211 * - In regular mode, this corresponds to 1212 * the right-hand side \f$ b_i \f$ of equation: 1213 * \f[ 1214 * \sum_j a_{i,j} x_j = b_i 1215 * \f] 1216 * - In least-squares mode (\ref NL_LEAST_SQUARES), this correspond to the 1217 * term \f$ b_i \f$ in: 1218 * \f[ 1219 * \left( \sum_j a_{i,j} x_j - b_i \right)^2 1220 * \f] 1221 * Usage: 1222 * \code 1223 * nlRowParameterd(NL_RIGHT_HAND_SIDE, bi); 1224 * nlBegin(NL_ROW); 1225 * ... 1226 * nlEnd(NL_ROW); 1227 * \endcode 1228 * \pre This function should be called between a 1229 * nlBegin(NL_ROW) / nlEnd(NL_ROW) pair, and at most once 1230 * (else an assertion failure is triggered). 1231 * \note The right hand side 1232 * is reset to zero after completion of nlEnd(NL_ROW). 1233 * \param[in] value value to be accumulated into the right hand side. 1234 */ 1235 NLAPI void NLAPIENTRY nlRightHandSide(NLdouble value); 1236 1237 1238 /** 1239 * \brief Sets the right-hand side of the current row when there are 1240 * several systems to be solved. 1241 * \param[in] k index of the system, in 0..nlGetInt(NL_NB_SYSTEMS)-1 1242 * \param[in] value the coefficient 1243 * \see nlRightHandSide() 1244 */ 1245 NLAPI void NLAPIENTRY nlMultiRightHandSide(NLuint k, NLdouble value); 1246 1247 /** 1248 * \brief Sets the row scaling for the next row. 1249 * \details 1250 * - if \ref NL_NORMALIZE_ROWS is not enabled, then 1251 * the coefficients are multiplied by the specified row scaling 1252 * coefficient \f$ s \f$ as follows when the row is completed: 1253 * \f[ 1254 * \begin{array}{lcl} 1255 * a_{i,j} & \leftarrow & a_{i,j} \times s \\ 1256 * b_i & \leftarrow & b_i \times s 1257 * \end{array} 1258 * \f] 1259 * - if \ref NL_NORMALIZE_ROWS is enabled, then 1260 * the coefficients are divided by the row length \f$ L \f$ 1261 * and multiplied by the specified row scaling 1262 * coefficient \f$ s \f$ as follows when the row is completed: 1263 * \f[ 1264 * \begin{array}{lcl} 1265 * L & \leftarrow & \sqrt{\sum_{j} a_{i,j}^2} \\ 1266 * a_{i,j} & \leftarrow & a_{i,j} \times s / L\\ 1267 * b_i & \leftarrow & b_i \times s / L 1268 * \end{array} 1269 * \f] 1270 * \param[in] value the row scaling. 1271 * \note The row scaling is used by the next row, and reset to 1.0 after 1272 * completion of nlEnd(NL_ROW). 1273 * \pre This function should be called after nlBegin(NL_MATRIX) 1274 * and before nlBegin(NL_ROW). 1275 */ 1276 NLAPI void NLAPIENTRY nlRowScaling(NLdouble value); 1277 1278 /** 1279 * @} 1280 * \name Solve 1281 * @{ 1282 */ 1283 1284 /** 1285 * \brief Solves the linear system in the current context. 1286 * \details This function should be called after nlEnd(NL_SYSTEM), 1287 * else an assertion failure is triggered. Once the function is 1288 * called, client code may get the value of the computed variables 1289 * using nlGetVariable(). 1290 */ 1291 NLAPI NLboolean NLAPIENTRY nlSolve(void); 1292 1293 1294 /** 1295 * \brief Updates the right hand side of the constructed system in 1296 * one call. 1297 * \param[in] values a pointer to an array of N doubles, where N 1298 * corresponds to the number of not locked variables. 1299 * \details If the current state is solved, it resets the current 1300 * state to constructed. This function cannot be called if 1301 * NL_NB_SYSTEMS is different from 1. 1302 */ 1303 NLAPI void NLAPIENTRY nlUpdateRightHandSide(NLdouble* values); 1304 1305 /** 1306 * @} 1307 * \name Buffers 1308 * @{ 1309 */ 1310 1311 /** 1312 * \brief The symbolic constant for variables buffer. 1313 * \details Used as an argument of nlEnable() / nlDisable() / nlIsEnabled() and 1314 * as an argument of nlBindBuffer. 1315 */ 1316 #define NL_VARIABLES_BUFFER 0x1000 1317 1318 /** 1319 * \brief Specifies a buffer binding to directly map user data to variables 1320 * instead of using nlGetVariable() / nlSetVariable() 1321 * \details NL_VARIABLES_BUFFER needs to be previouslyu nlEnabled() else 1322 * this function has no effect. 1323 * \param[in] buffer the type of the buffer, NL_VARIABLES_BUFFER is the 1324 * only supported value 1325 * \param[in] k the index of the buffer. If type = NL_VARIABLES_BUFFER, this 1326 * corresponds to the index of the linear system (0 if there is a single 1327 * linear system). 1328 * \param[in] addr the address of the array to be bound. 1329 * \param[in] stride number of bytes between two consecutive elements. 1330 */ 1331 NLAPI void NLAPIENTRY nlBindBuffer( 1332 NLenum buffer, NLuint k, void* addr, NLuint stride 1333 ); 1334 1335 1336 /** 1337 * @} 1338 * \name EigenSolver 1339 * @{ 1340 */ 1341 1342 /** 1343 * \brief Constant for nlMatrixMode() 1344 */ 1345 #define NL_STIFFNESS_MATRIX 0x3001 1346 1347 /** 1348 * \brief Constant for nlMatrixMode() 1349 */ 1350 #define NL_MASS_MATRIX 0x3002 1351 1352 /** 1353 * \brief Specifies to which matrix the subsequent calls 1354 * to nlBegin(), nlEnd(), nlCoefficient(), nlAddIJCoefficient() 1355 * will be applied. 1356 * \param[in] matrix one of NL_STIFFNESS_MATRIX (default), NL_MASS_MATRIX 1357 * \details Calling nlMatrixMode() resets the current row to 0. 1358 */ 1359 NLAPI void NLAPIENTRY nlMatrixMode(NLenum matrix); 1360 1361 /** 1362 * \brief Symbolic constant for nlEigenSolverParameteri(), 1363 * number of eigenpairs to compute. 1364 */ 1365 #define NL_NB_EIGENS NL_NB_SYSTEMS 1366 1367 /** 1368 * \brief Symbolic constant for nlEigenSolverParameteri(), 1369 * maximum number of iterations. 1370 */ 1371 #define NL_EIGEN_MAX_ITERATIONS NL_MAX_ITERATIONS 1372 1373 /** 1374 * \brief Symbolic constant for nlEigenSolverParameterd(), 1375 * convergence threshold. 1376 */ 1377 #define NL_EIGEN_THRESHOLD NL_THRESHOLD 1378 1379 /** 1380 * \brief Symbolic constant for nlEigenSolverParameterd(), 1381 * name of the eigen solver to be used. 1382 */ 1383 #define NL_EIGEN_SOLVER 0x2000 1384 1385 /** 1386 * \brief Symbolic constant for nlEigenSolverParameterd(), 1387 * shift parameter for the shift-invert transform 1388 */ 1389 #define NL_EIGEN_SHIFT 0x2001 1390 1391 /** 1392 * \brief Symbolic constant for nlEnable() / nlDisable() / nlIsEnabled(), 1393 * shift-invert spectral transform. 1394 */ 1395 #define NL_EIGEN_SHIFT_INVERT 0x2002 1396 1397 /** 1398 * \brief Sets a floating-point parameter of the eigen solver. 1399 * \param pname symbolic name of the parameter, 1400 * one of NL_EIGEN_SHIFT, NL_EIGEN_THRESHOLD. 1401 */ 1402 NLAPI void NLAPIENTRY nlEigenSolverParameterd( 1403 NLenum pname, NLdouble val 1404 ); 1405 1406 /** 1407 * \brief Sets an integer parameter of the eigen solver. 1408 * \param pname symbolic name of the parameter, 1409 * one of NL_EIGEN_SOLVER, NL_NB_EIGENS, NL_NB_VARIABLES, 1410 * NL_EIGEN_MAX_ITERATIONS, NL_SYMMETRIC. 1411 */ 1412 NLAPI void NLAPIENTRY nlEigenSolverParameteri( 1413 NLenum pname, NLint val 1414 ); 1415 1416 /** 1417 * \brief Calls the eigen solver. 1418 */ 1419 NLAPI void NLAPIENTRY nlEigenSolve(void); 1420 1421 1422 /** 1423 * \brief Gets an eigenvalue. 1424 * \param i index of the eigenvalue. 1425 * \return the \p i th eigenvalue. 1426 */ 1427 NLAPI double NLAPIENTRY nlGetEigenValue(NLuint i); 1428 1429 /** 1430 * @} 1431 * \name Logging and messages 1432 * @{ 1433 */ 1434 1435 /** 1436 * \brief Function pointer type for user printf function. 1437 */ 1438 typedef int (*NLprintfFunc)(const char* format, ...); 1439 1440 /** 1441 * \brief Function pointer type for user fprintf function. 1442 */ 1443 typedef int (*NLfprintfFunc)(FILE* out, const char* format, ...); 1444 1445 /** 1446 * \brief Specifies user functions for printing messages. 1447 */ 1448 NLAPI void NLAPIENTRY nlPrintfFuncs(NLprintfFunc f1, NLfprintfFunc f2); 1449 1450 1451 /** 1452 * @} 1453 */ 1454 1455 #ifdef __cplusplus 1456 } 1457 #endif 1458 1459 #include "nl_ext.h" 1460 #include "nl_64.h" 1461 1462 /*************************************************************************/ 1463 1464 #endif 1465