| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Copyright (c) 2000-2022 Inria | ||
| 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 | * Contact: Bruno Levy | ||
| 30 | * | ||
| 31 | * https://www.inria.fr/fr/bruno-levy | ||
| 32 | * | ||
| 33 | * Inria, | ||
| 34 | * Domaine de Voluceau, | ||
| 35 | * 78150 Le Chesnay - Rocquencourt | ||
| 36 | * FRANCE | ||
| 37 | * | ||
| 38 | */ | ||
| 39 | |||
| 40 | #include <geogram/NL/nl.h> | ||
| 41 | #include <stdio.h> | ||
| 42 | #include <string.h> | ||
| 43 | |||
| 44 | #ifdef __EMSCRIPTEN__ | ||
| 45 | #include <emscripten.h> | ||
| 46 | #endif | ||
| 47 | |||
| 48 | /** | ||
| 49 | * \brief Tests OpenNL solve with | ||
| 50 | * a simple linear system. | ||
| 51 | * \details | ||
| 52 | * Solve \f$ \left[ \begin{array}{ll} 1 & 2 \\ 3 & 4 \end{array} \right] | ||
| 53 | * \left[ \begin{array}{l} x \\ y \end{array} \right] | ||
| 54 | * = \left[ \begin{array}{l} 5 \\ 6 \end{array} \right] \f$ | ||
| 55 | */ | ||
| 56 | 6 | static void test_simple_linear_solve(NLint solver) { | |
| 57 | 6 | NLboolean symmetric = NL_FALSE; | |
| 58 | |||
| 59 | 6 | printf("\n"); | |
| 60 | 6 | printf("Testing linear solve\n"); | |
| 61 | 6 | printf("====================\n"); | |
| 62 | |||
| 63 | |||
| 64 | |||
| 65 |
6/8✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
6 | switch(solver) { |
| 66 | 1 | case NL_SOLVER_DEFAULT: | |
| 67 | 1 | printf("Using default solver (BiCGStab)\n"); | |
| 68 | 1 | break; | |
| 69 | ✗ | case NL_CG: | |
| 70 | ✗ | printf("Using CG\n"); | |
| 71 | ✗ | symmetric = NL_TRUE; | |
| 72 | ✗ | break; | |
| 73 | 1 | case NL_GMRES: | |
| 74 | 1 | printf("Using GMRES\n"); | |
| 75 | 1 | break; | |
| 76 | 1 | case NL_BICGSTAB: | |
| 77 | 1 | printf("Using BiCGSTAB\n"); | |
| 78 | 1 | break; | |
| 79 | 1 | case NL_PERM_SUPERLU_EXT: | |
| 80 | 1 | printf("Using SUPERLU with permutation\n"); | |
| 81 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if(nlInitExtension("SUPERLU")) { |
| 82 | 1 | printf("...SUPERLU extension successfully initialized\n"); | |
| 83 | } else { | ||
| 84 | ✗ | printf("...failed to initialize SUPERLU extension\n"); | |
| 85 | ✗ | printf("Needs Linux/shared librariess/-DGEO_DYNAMIC_LIBS\n"); | |
| 86 | ✗ | return; | |
| 87 | } | ||
| 88 | 1 | break; | |
| 89 | 1 | case NL_SUPERLU_EXT: | |
| 90 | 1 | printf("Using SUPERLU\n"); | |
| 91 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if(nlInitExtension("SUPERLU")) { |
| 92 | 1 | printf("...SUPERLU extension successfully initialized\n"); | |
| 93 | } else { | ||
| 94 | ✗ | printf("...failed to initialize SUPERLU extension\n"); | |
| 95 | ✗ | printf("Needs Linux/shared librariess/-DGEO_DYNAMIC_LIBS\n"); | |
| 96 | ✗ | return; | |
| 97 | } | ||
| 98 | 1 | break; | |
| 99 | 1 | case NL_CHOLMOD_EXT: | |
| 100 | 1 | symmetric = NL_TRUE; | |
| 101 | 1 | printf("using CHOLMOD\n"); | |
| 102 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if(nlInitExtension("CHOLMOD")) { |
| 103 | ✗ | printf("...CHOLMOD extension successfully initialized\n"); | |
| 104 | }else { | ||
| 105 | 1 | printf("...failed to initialize CHOLMOD extension\n"); | |
| 106 | 1 | printf("Needs Linux/shared librariess/-DGEO_DYNAMIC_LIBS\n"); | |
| 107 | 1 | return; | |
| 108 | } | ||
| 109 | ✗ | break; | |
| 110 | } | ||
| 111 | |||
| 112 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if(symmetric) { |
| 113 | ✗ | printf("Creating linear system:\n"); | |
| 114 | ✗ | printf(" 1.0*x0 - 5.0*x1 = 5.0\n"); | |
| 115 | ✗ | printf(" -5.0*x0 + 4.0*x1 = 6.0\n"); | |
| 116 | } else { | ||
| 117 | 5 | printf("Creating linear system:\n"); | |
| 118 | 5 | printf(" 1.0*x0 + 2.0*x1 = 5.0\n"); | |
| 119 | 5 | printf(" 3.0*x0 + 4.0*x1 = 6.0\n"); | |
| 120 | } | ||
| 121 | |||
| 122 | /* Create and initialize OpenNL context */ | ||
| 123 | 5 | nlNewContext(); | |
| 124 | 5 | nlSolverParameteri(NL_NB_VARIABLES, 2); | |
| 125 | 5 | nlSolverParameteri(NL_SOLVER, solver); | |
| 126 | |||
| 127 | /* Build system */ | ||
| 128 | 5 | nlBegin(NL_SYSTEM); | |
| 129 | 5 | nlBegin(NL_MATRIX); | |
| 130 | 5 | nlBegin(NL_ROW); | |
| 131 | 5 | nlCoefficient(0, 1.0); | |
| 132 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | nlCoefficient(1, symmetric ? -5.0 : 2.0); |
| 133 | 5 | nlRightHandSide(5.0); | |
| 134 | 5 | nlEnd(NL_ROW); | |
| 135 | 5 | nlBegin(NL_ROW); | |
| 136 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | nlCoefficient(0, symmetric ? -5.0 : 3.0); |
| 137 | 5 | nlCoefficient(1, 4.0); | |
| 138 | 5 | nlRightHandSide(6.0); | |
| 139 | 5 | nlEnd(NL_ROW); | |
| 140 | 5 | nlEnd(NL_MATRIX); | |
| 141 | 5 | nlEnd(NL_SYSTEM); | |
| 142 | |||
| 143 | /* Solve and get solution */ | ||
| 144 | 5 | printf("Solving...\n"); | |
| 145 | 5 | nlSolve(); | |
| 146 | |||
| 147 | |||
| 148 | 5 | printf("Solution: x0=%f x1=%f\n", nlGetVariable(0), nlGetVariable(1)); | |
| 149 | |||
| 150 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if(symmetric) { |
| 151 | ✗ | printf("Verifying:\n"); | |
| 152 | ✗ | printf( | |
| 153 | " 1.0*x0 - 5.0*x1 = %f\n", | ||
| 154 | ✗ | 1.0 * nlGetVariable(0) - 5.0 * nlGetVariable(1) | |
| 155 | ); | ||
| 156 | ✗ | printf( | |
| 157 | " -5.0*x0 + 4.0*x1 = %f\n", | ||
| 158 | ✗ | -5.0 * nlGetVariable(0) + 4.0 * nlGetVariable(1) | |
| 159 | ); | ||
| 160 | } else { | ||
| 161 | 5 | printf("Verifying:\n"); | |
| 162 | 5 | printf( | |
| 163 | " 1.0*x0 + 2.0*x1 = %f\n", | ||
| 164 | 5 | 1.0 * nlGetVariable(0) + 2.0 * nlGetVariable(1) | |
| 165 | ); | ||
| 166 | 5 | printf( | |
| 167 | " 3.0*x0 + 4.0*x1 = %f\n", | ||
| 168 | 5 | 3.0 * nlGetVariable(0) + 4.0 * nlGetVariable(1) | |
| 169 | ); | ||
| 170 | } | ||
| 171 | |||
| 172 | /* Cleanup */ | ||
| 173 | 5 | nlDeleteContext(nlGetCurrent()); | |
| 174 | } | ||
| 175 | |||
| 176 | 4 | static void test_least_squares_regression( | |
| 177 | NLboolean origin, NLboolean use_SSOR_precond | ||
| 178 | ) { | ||
| 179 | 4 | NLint nb_pts = 7, k; | |
| 180 | 4 | NLdouble XY[7][2] = { | |
| 181 | {1.0, 3.5}, | ||
| 182 | {2.0, 3.8}, | ||
| 183 | {3.0, 5.5}, | ||
| 184 | {4.0, 5.4}, | ||
| 185 | {5.0, 6.3}, | ||
| 186 | {6.0, 8.2}, | ||
| 187 | {7.0, 9.5}, | ||
| 188 | }; | ||
| 189 | |||
| 190 | 4 | printf("\n"); | |
| 191 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if(origin) { |
| 192 | 2 | printf("Testing constrained least-squares regression\n"); | |
| 193 | 2 | printf("============================================\n"); | |
| 194 | } else { | ||
| 195 | 2 | printf("Testing least-squares regression\n"); | |
| 196 | 2 | printf("================================\n"); | |
| 197 | } | ||
| 198 | |||
| 199 | |||
| 200 | 4 | nlNewContext(); | |
| 201 | 4 | nlSolverParameteri(NL_NB_VARIABLES, 2); | |
| 202 | 4 | nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); | |
| 203 | |||
| 204 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if(use_SSOR_precond) { |
| 205 | 2 | printf("Using SSOR preconditioner\n"); | |
| 206 | 2 | nlSolverParameteri(NL_PRECONDITIONER, NL_PRECOND_SSOR); | |
| 207 | } else { | ||
| 208 | 2 | printf("Using default preconditioner (Jacobi)\n"); | |
| 209 | } | ||
| 210 | |||
| 211 | 4 | nlBegin(NL_SYSTEM); | |
| 212 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if(origin) { |
| 213 | 2 | nlLockVariable(1); | |
| 214 | 2 | nlSetVariable(1,0.0); | |
| 215 | } | ||
| 216 | 4 | nlBegin(NL_MATRIX); | |
| 217 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 4 times.
|
32 | for(k=0; k<nb_pts; ++k) { |
| 218 | 28 | nlBegin(NL_ROW); | |
| 219 | 28 | nlCoefficient(0, XY[k][0]); | |
| 220 | 28 | nlCoefficient(1, 1.0); | |
| 221 | 28 | nlRightHandSide(XY[k][1]); | |
| 222 | 28 | nlEnd(NL_ROW); | |
| 223 | } | ||
| 224 | 4 | nlEnd(NL_MATRIX); | |
| 225 | 4 | nlEnd(NL_SYSTEM); | |
| 226 | |||
| 227 | /* Solve and get solution */ | ||
| 228 | 4 | printf("Solving...\n"); | |
| 229 | 4 | nlSolve(); | |
| 230 | |||
| 231 | 4 | printf("Solution: a=%f b=%f\n", nlGetVariable(0), nlGetVariable(1)); | |
| 232 | |||
| 233 | /* Cleanup */ | ||
| 234 | 4 | nlDeleteContext(nlGetCurrent()); | |
| 235 | 4 | } | |
| 236 | |||
| 237 | |||
| 238 | 1 | int main(int argc, char** argv) { | |
| 239 | |||
| 240 | 1 | nlInitialize(argc, argv); | |
| 241 | |||
| 242 | 1 | test_simple_linear_solve(NL_SOLVER_DEFAULT); | |
| 243 | 1 | test_simple_linear_solve(NL_GMRES); | |
| 244 | 1 | test_simple_linear_solve(NL_BICGSTAB); | |
| 245 | 1 | test_simple_linear_solve(NL_SUPERLU_EXT); | |
| 246 | 1 | test_simple_linear_solve(NL_PERM_SUPERLU_EXT); | |
| 247 | 1 | test_simple_linear_solve(NL_CHOLMOD_EXT); | |
| 248 | |||
| 249 | 1 | test_least_squares_regression(NL_FALSE, NL_FALSE); | |
| 250 | 1 | test_least_squares_regression(NL_FALSE, NL_TRUE); | |
| 251 | 1 | test_least_squares_regression(NL_TRUE, NL_FALSE); | |
| 252 | 1 | test_least_squares_regression(NL_TRUE, NL_TRUE); | |
| 253 | |||
| 254 | |||
| 255 | 1 | return 0; | |
| 256 | } | ||
| 257 |