1 // Copyright (C) 2007 Davis E. King (davis@dlib.net) 2 // License: Boost Software License See LICENSE.txt for the full license. 3 #undef DLIB_SVm_KERNEL_ABSTRACT_ 4 #ifdef DLIB_SVm_KERNEL_ABSTRACT_ 5 6 #include <cmath> 7 #include <limits> 8 #include <sstream> 9 #include "../matrix/matrix_abstract.h" 10 #include "../algs.h" 11 #include "../serialize.h" 12 13 namespace dlib 14 { 15 16 // ---------------------------------------------------------------------------------------- 17 // ---------------------------------------------------------------------------------------- 18 /*!A Kernel_Function_Objects */ 19 // ---------------------------------------------------------------------------------------- 20 // ---------------------------------------------------------------------------------------- 21 22 /*! 23 WHAT IS A KERNEL FUNCTION OBJECT? 24 In the context of the dlib library documentation a kernel function object 25 is an object with an interface with the following properties: 26 - a public typedef named sample_type 27 - a public typedef named scalar_type which should be a float, double, or 28 long double type. 29 - an overloaded operator() that operates on two items of sample_type 30 and returns a scalar_type. 31 (e.g. scalar_type val = kernel_function(sample1,sample2); 32 would be a valid expression) 33 - a public typedef named mem_manager_type that is an implementation of 34 dlib/memory_manager/memory_manager_kernel_abstract.h or 35 dlib/memory_manager_global/memory_manager_global_kernel_abstract.h or 36 dlib/memory_manager_stateless/memory_manager_stateless_kernel_abstract.h 37 - an overloaded == operator that tells you if two kernels are 38 identical or not. 39 40 THREAD SAFETY 41 For a kernel function to be threadsafe it means that it must be safe to 42 evaluate an expression like val = kernel_function(sample1,sample2) 43 simultaneously from multiple threads, even when the threads operate on the same 44 object instances (i.e. kernel_function, sample1, and sample2). The most common 45 way to make this safe is to ensure that the kernel function does not mutate any 46 data, either in itself or in its arguments. 47 48 For examples of kernel functions see the following objects 49 (e.g. the radial_basis_kernel). 50 !*/ 51 52 template < 53 typename T 54 > 55 struct radial_basis_kernel 56 { 57 /*! 58 REQUIREMENTS ON T 59 T must be a dlib::matrix object 60 61 WHAT THIS OBJECT REPRESENTS 62 This object represents a radial basis function kernel 63 64 THREAD SAFETY 65 This kernel is threadsafe. 66 !*/ 67 68 typedef typename T::type scalar_type; 69 typedef T sample_type; 70 typedef typename T::mem_manager_type mem_manager_type; 71 72 const scalar_type gamma; 73 74 radial_basis_kernel( 75 ); 76 /*! 77 ensures 78 - #gamma == 0.1 79 !*/ 80 81 radial_basis_kernel( 82 const radial_basis_kernel& k 83 ); 84 /*! 85 ensures 86 - #gamma == k.gamma 87 !*/ 88 89 radial_basis_kernel( 90 const scalar_type g 91 ); 92 /*! 93 ensures 94 - #gamma == g 95 !*/ 96 97 scalar_type operator() ( 98 const sample_type& a, 99 const sample_type& b 100 ) const; 101 /*! 102 requires 103 - a.nc() == 1 104 - b.nc() == 1 105 - a.nr() == b.nr() 106 ensures 107 - returns exp(-gamma * ||a-b||^2) 108 !*/ 109 110 radial_basis_kernel& operator= ( 111 const radial_basis_kernel& k 112 ); 113 /*! 114 ensures 115 - #gamma = k.gamma 116 - returns *this 117 !*/ 118 119 bool operator== ( 120 const radial_basis_kernel& k 121 ) const; 122 /*! 123 ensures 124 - if (k and *this are identical) then 125 - returns true 126 - else 127 - returns false 128 !*/ 129 130 }; 131 132 template < 133 typename T 134 > 135 void serialize ( 136 const radial_basis_kernel<T>& item, 137 std::ostream& out 138 ); 139 /*! 140 provides serialization support for radial_basis_kernel 141 !*/ 142 143 template < 144 typename T 145 > 146 void deserialize ( 147 radial_basis_kernel<T>& item, 148 std::istream& in 149 ); 150 /*! 151 provides deserialization support for radial_basis_kernel 152 !*/ 153 154 // ---------------------------------------------------------------------------------------- 155 156 template < 157 typename T 158 > 159 struct sigmoid_kernel 160 { 161 /*! 162 REQUIREMENTS ON T 163 T must be a dlib::matrix object 164 165 WHAT THIS OBJECT REPRESENTS 166 This object represents a sigmoid kernel 167 168 THREAD SAFETY 169 This kernel is threadsafe. 170 !*/ 171 172 typedef typename T::type scalar_type; 173 typedef T sample_type; 174 typedef typename T::mem_manager_type mem_manager_type; 175 176 const scalar_type gamma; 177 const scalar_type coef; 178 179 sigmoid_kernel( 180 ); 181 /*! 182 ensures 183 - #gamma == 0.1 184 - #coef == -1.0 185 !*/ 186 187 sigmoid_kernel( 188 const sigmoid_kernel& k 189 ); 190 /*! 191 ensures 192 - #gamma == k.gamma 193 - #coef == k.coef 194 !*/ 195 196 sigmoid_kernel( 197 const scalar_type g, 198 const scalar_type c 199 ); 200 /*! 201 ensures 202 - #gamma == g 203 - #coef == c 204 !*/ 205 206 scalar_type operator() ( 207 const sample_type& a, 208 const sample_type& b 209 ) const; 210 /*! 211 requires 212 - a.nc() == 1 213 - b.nc() == 1 214 - a.nr() == b.nr() 215 ensures 216 - returns tanh(gamma*trans(a)*b + coef) 217 !*/ 218 219 sigmoid_kernel& operator= ( 220 const sigmoid_kernel& k 221 ); 222 /*! 223 ensures 224 - #gamma = k.gamma 225 - #coef = k.coef 226 - returns *this 227 !*/ 228 229 bool operator== ( 230 const sigmoid_kernel& k 231 ) const; 232 /*! 233 ensures 234 - if (k and *this are identical) then 235 - returns true 236 - else 237 - returns false 238 !*/ 239 }; 240 241 template < 242 typename T 243 > 244 void serialize ( 245 const sigmoid_kernel<T>& item, 246 std::ostream& out 247 ); 248 /*! 249 provides serialization support for sigmoid_kernel 250 !*/ 251 252 template < 253 typename T 254 > 255 void deserialize ( 256 sigmoid_kernel<T>& item, 257 std::istream& in 258 ); 259 /*! 260 provides deserialization support for sigmoid_kernel 261 !*/ 262 263 264 // ---------------------------------------------------------------------------------------- 265 266 template < 267 typename T 268 > 269 struct polynomial_kernel 270 { 271 /*! 272 REQUIREMENTS ON T 273 T must be a dlib::matrix object 274 275 WHAT THIS OBJECT REPRESENTS 276 This object represents a polynomial kernel 277 278 THREAD SAFETY 279 This kernel is threadsafe. 280 !*/ 281 282 typedef typename T::type scalar_type; 283 typedef T sample_type; 284 typedef typename T::mem_manager_type mem_manager_type; 285 286 const scalar_type gamma; 287 const scalar_type coef; 288 const scalar_type degree; 289 290 polynomial_kernel( 291 ); 292 /*! 293 ensures 294 - #gamma == 1 295 - #coef == 0 296 - #degree == 1 297 !*/ 298 299 polynomial_kernel( 300 const polynomial_kernel& k 301 ); 302 /*! 303 ensures 304 - #gamma == k.gamma 305 - #coef == k.coef 306 - #degree == k.degree 307 !*/ 308 309 polynomial_kernel( 310 const scalar_type g, 311 const scalar_type c, 312 const scalar_type d 313 ); 314 /*! 315 ensures 316 - #gamma == g 317 - #coef == c 318 - #degree == d 319 !*/ 320 321 scalar_type operator() ( 322 const sample_type& a, 323 const sample_type& b 324 ) const; 325 /*! 326 requires 327 - a.nc() == 1 328 - b.nc() == 1 329 - a.nr() == b.nr() 330 ensures 331 - returns pow(gamma*trans(a)*b + coef, degree) 332 !*/ 333 334 polynomial_kernel& operator= ( 335 const polynomial_kernel& k 336 ); 337 /*! 338 ensures 339 - #gamma = k.gamma 340 - #coef = k.coef 341 - #degree = k.degree 342 - returns *this 343 !*/ 344 345 bool operator== ( 346 const polynomial_kernel& k 347 ) const; 348 /*! 349 ensures 350 - if (k and *this are identical) then 351 - returns true 352 - else 353 - returns false 354 !*/ 355 }; 356 357 template < 358 typename T 359 > 360 void serialize ( 361 const polynomial_kernel<T>& item, 362 std::ostream& out 363 ); 364 /*! 365 provides serialization support for polynomial_kernel 366 !*/ 367 368 template < 369 typename T 370 > 371 void deserialize ( 372 polynomial_kernel<T>& item, 373 std::istream& in 374 ); 375 /*! 376 provides deserialization support for polynomial_kernel 377 !*/ 378 379 // ---------------------------------------------------------------------------------------- 380 381 template < 382 typename T 383 > 384 struct linear_kernel 385 { 386 /*! 387 REQUIREMENTS ON T 388 T must be a dlib::matrix object 389 390 WHAT THIS OBJECT REPRESENTS 391 This object represents a linear function kernel 392 393 THREAD SAFETY 394 This kernel is threadsafe. 395 !*/ 396 397 typedef typename T::type scalar_type; 398 typedef T sample_type; 399 typedef typename T::mem_manager_type mem_manager_type; 400 401 scalar_type operator() ( 402 const sample_type& a, 403 const sample_type& b 404 ) const; 405 /*! 406 requires 407 - a.nc() == 1 408 - b.nc() == 1 409 - a.nr() == b.nr() 410 ensures 411 - returns trans(a)*b 412 !*/ 413 414 bool operator== ( 415 const linear_kernel& k 416 ) const; 417 /*! 418 ensures 419 - returns true 420 !*/ 421 }; 422 423 template < 424 typename T 425 > 426 void serialize ( 427 const linear_kernel<T>& item, 428 std::ostream& out 429 ); 430 /*! 431 provides serialization support for linear_kernel 432 !*/ 433 434 template < 435 typename T 436 > 437 void deserialize ( 438 linear_kernel<T>& item, 439 std::istream& in 440 ); 441 /*! 442 provides deserialization support for linear_kernel 443 !*/ 444 445 // ---------------------------------------------------------------------------------------- 446 447 template < 448 typename T 449 > 450 struct histogram_intersection_kernel 451 { 452 /*! 453 REQUIREMENTS ON T 454 T must be a dlib::matrix object 455 456 WHAT THIS OBJECT REPRESENTS 457 This object represents a histogram intersection kernel kernel 458 459 THREAD SAFETY 460 This kernel is threadsafe. 461 !*/ 462 463 typedef typename T::type scalar_type; 464 typedef T sample_type; 465 typedef typename T::mem_manager_type mem_manager_type; 466 467 scalar_type operator() ( 468 const sample_type& a, 469 const sample_type& b 470 ) const; 471 /*! 472 requires 473 - is_vector(a) 474 - is_vector(b) 475 - a.size() == b.size() 476 - min(a) >= 0 477 - min(b) >= 0 478 ensures 479 - returns sum over all i: std::min(a(i), b(i)) 480 !*/ 481 482 bool operator== ( 483 const histogram_intersection_kernel& k 484 ) const; 485 /*! 486 ensures 487 - returns true 488 !*/ 489 }; 490 491 template < 492 typename T 493 > 494 void serialize ( 495 const histogram_intersection_kernel<T>& item, 496 std::ostream& out 497 ); 498 /*! 499 provides serialization support for histogram_intersection_kernel 500 !*/ 501 502 template < 503 typename T 504 > 505 void deserialize ( 506 histogram_intersection_kernel<T>& item, 507 std::istream& in 508 ); 509 /*! 510 provides deserialization support for histogram_intersection_kernel 511 !*/ 512 513 // ---------------------------------------------------------------------------------------- 514 515 template < 516 typename T 517 > 518 struct offset_kernel 519 { 520 /*! 521 REQUIREMENTS ON T 522 T must be a kernel object (e.g. radial_basis_kernel, polynomial_kernel, etc.) 523 524 WHAT THIS OBJECT REPRESENTS 525 This object represents a kernel with a fixed value offset 526 added to it. 527 528 THREAD SAFETY 529 This kernel is threadsafe. 530 !*/ 531 532 typedef typename T::scalar_type scalar_type; 533 typedef typename T::sample_type sample_type; 534 typedef typename T::mem_manager_type mem_manager_type; 535 536 const T kernel; 537 const scalar_type offset; 538 539 offset_kernel( 540 ); 541 /*! 542 ensures 543 - #offset == 0.01 544 !*/ 545 546 offset_kernel( 547 const offset_kernel& k 548 ); 549 /*! 550 ensures 551 - #offset == k.offset 552 - #kernel == k.kernel 553 !*/ 554 555 offset_kernel( 556 const T& k, 557 const scalar_type& off 558 ); 559 /*! 560 ensures 561 - #kernel == k 562 - #offset == off 563 !*/ 564 565 scalar_type operator() ( 566 const sample_type& a, 567 const sample_type& b 568 ) const; 569 /*! 570 ensures 571 - returns kernel(a,b) + offset 572 !*/ 573 574 offset_kernel& operator= ( 575 const offset_kernel& k 576 ); 577 /*! 578 ensures 579 - #offset == k.offset 580 - #kernel == k.kernel 581 !*/ 582 583 bool operator== ( 584 const offset_kernel& k 585 ) const; 586 /*! 587 ensures 588 - if (k and *this are identical) then 589 - returns true 590 - else 591 - returns false 592 !*/ 593 }; 594 595 template < 596 typename T 597 > 598 void serialize ( 599 const offset_kernel<T>& item, 600 std::ostream& out 601 ); 602 /*! 603 provides serialization support for offset_kernel 604 !*/ 605 606 template < 607 typename T 608 > 609 void deserialize ( 610 offset_kernel<T>& item, 611 std::istream& in 612 ); 613 /*! 614 provides deserialization support for offset_kernel 615 !*/ 616 617 // ---------------------------------------------------------------------------------------- 618 // ---------------------------------------------------------------------------------------- 619 // ---------------------------------------------------------------------------------------- 620 621 template < 622 typename kernel_type 623 > 624 struct kernel_derivative 625 { 626 /*! 627 REQUIREMENTS ON kernel_type 628 kernel_type must be one of the following kernel types: 629 - radial_basis_kernel 630 - polynomial_kernel 631 - sigmoid_kernel 632 - linear_kernel 633 - offset_kernel 634 635 WHAT THIS OBJECT REPRESENTS 636 This is a function object that computes the derivative of a kernel 637 function object. 638 639 THREAD SAFETY 640 It is always safe to use distinct instances of this object in different 641 threads. However, when a single instance is shared between threads then 642 the following rules apply: 643 Instances of this object are allowed to have a mutable cache which is 644 used by const member functions. Therefore, it is not safe to use one 645 instance of this object from multiple threads (unless protected by a 646 mutex). 647 !*/ 648 649 typedef typename kernel_type::scalar_type scalar_type; 650 typedef typename kernel_type::sample_type sample_type; 651 typedef typename kernel_type::mem_manager_type mem_manager_type; 652 653 kernel_derivative( 654 const kernel_type& k_ 655 ); 656 /*! 657 ensures 658 - this object will return derivatives of the kernel object k_ 659 - #k == k_ 660 !*/ 661 662 const sample_type operator() ( 663 const sample_type& x, 664 const sample_type& y 665 ) const; 666 /*! 667 ensures 668 - returns the derivative of k with respect to y. 669 !*/ 670 671 const kernel_type& k; 672 }; 673 674 // ---------------------------------------------------------------------------------------- 675 676 } 677 678 #endif // DLIB_SVm_KERNEL_ABSTRACT_ 679 680 681 682