commit a1bf986365165e8446561ec3391d56af63cafa02 Author: rmontanana Date: Sun Jun 22 11:25:27 2025 +0000 deploy: d6dc083a5a2146434e20fd26847e1b8ab5632231 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/annotated.html b/annotated.html new file mode 100644 index 0000000..6d9e8eb --- /dev/null +++ b/annotated.html @@ -0,0 +1,95 @@ + + + + + + + +SVM Classifier C++: Class List + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 12]
+ + + + + + + + + +
 Nsvm_classifier
 CDataConverterData converter between libtorch tensors and SVM library formats
 CEvaluationMetricsModel evaluation metrics
 CMulticlassStrategyBaseAbstract base class for multiclass classification strategies
 COneVsOneStrategyOne-vs-One (OvO) multiclass strategy
 COneVsRestStrategyOne-vs-Rest (OvR) multiclass strategy
 CPredictionResultPrediction result structure
 CSVMClassifierSupport Vector Machine Classifier with scikit-learn compatible API
 CTrainingMetricsTraining metrics structure
+
+
+ + + + diff --git a/bc_s.png b/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/bc_s.png differ diff --git a/bc_sd.png b/bc_sd.png new file mode 100644 index 0000000..31ca888 Binary files /dev/null and b/bc_sd.png differ diff --git a/classes.html b/classes.html new file mode 100644 index 0000000..854714c --- /dev/null +++ b/classes.html @@ -0,0 +1,106 @@ + + + + + + + +SVM Classifier C++: Class Index + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class Index
+
+
+
D | E | M | O | P | S | T
+
+
+
D
+
DataConverter (svm_classifier)
+
+
E
+
EvaluationMetrics (svm_classifier)
+
+
M
+
MulticlassStrategyBase (svm_classifier)
+
+
O
+
OneVsOneStrategy (svm_classifier)
OneVsRestStrategy (svm_classifier)
+
+
P
+
PredictionResult (svm_classifier)
+
+
S
+
SVMClassifier (svm_classifier)
+
+
T
+
TrainingMetrics (svm_classifier)
+
+
+ + + + diff --git a/classsvm__classifier_1_1DataConverter-members.html b/classsvm__classifier_1_1DataConverter-members.html new file mode 100644 index 0000000..64b54e8 --- /dev/null +++ b/classsvm__classifier_1_1DataConverter-members.html @@ -0,0 +1,119 @@ + + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
svm_classifier::DataConverter Member List
+
+
+ +

This is the complete list of members for svm_classifier::DataConverter, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
cleanup()svm_classifier::DataConverter
cleanup()svm_classifier::DataConverter
DataConverter()svm_classifier::DataConverter
DataConverter()svm_classifier::DataConverter
from_decision_values(const std::vector< std::vector< double > > &decision_values)svm_classifier::DataConverter
from_decision_values(const std::vector< std::vector< double > > &decision_values)svm_classifier::DataConverter
from_predictions(const std::vector< double > &predictions)svm_classifier::DataConverter
from_predictions(const std::vector< double > &predictions)svm_classifier::DataConverter
from_probabilities(const std::vector< std::vector< double > > &probabilities)svm_classifier::DataConverter
from_probabilities(const std::vector< std::vector< double > > &probabilities)svm_classifier::DataConverter
get_n_features() constsvm_classifier::DataConverterinline
get_n_features() constsvm_classifier::DataConverterinline
get_n_samples() constsvm_classifier::DataConverterinline
get_n_samples() constsvm_classifier::DataConverterinline
get_sparse_threshold() constsvm_classifier::DataConverterinline
get_sparse_threshold() constsvm_classifier::DataConverterinline
set_sparse_threshold(double threshold)svm_classifier::DataConverterinline
set_sparse_threshold(double threshold)svm_classifier::DataConverterinline
to_feature_node(const torch::Tensor &sample)svm_classifier::DataConverter
to_feature_node(const torch::Tensor &sample)svm_classifier::DataConverter
to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())svm_classifier::DataConverter
to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())svm_classifier::DataConverter
to_svm_node(const torch::Tensor &sample)svm_classifier::DataConverter
to_svm_node(const torch::Tensor &sample)svm_classifier::DataConverter
to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())svm_classifier::DataConverter
to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())svm_classifier::DataConverter
validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())svm_classifier::DataConverter
validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())svm_classifier::DataConverter
~DataConverter()svm_classifier::DataConverter
~DataConverter()svm_classifier::DataConverter
+ + + + diff --git a/classsvm__classifier_1_1DataConverter.html b/classsvm__classifier_1_1DataConverter.html new file mode 100644 index 0000000..cc16e4d --- /dev/null +++ b/classsvm__classifier_1_1DataConverter.html @@ -0,0 +1,1042 @@ + + + + + + + +SVM Classifier C++: svm_classifier::DataConverter Class Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+ +
svm_classifier::DataConverter Class Reference
+
+
+ +

Data converter between libtorch tensors and SVM library formats. + More...

+ +

#include <data_converter.hpp>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 DataConverter ()
 Default constructor.
 
 ~DataConverter ()
 Destructor - cleans up allocated memory.
 
std::unique_ptr< svm_problem > to_svm_problem (const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
 Convert PyTorch tensors to libsvm format.
 
std::unique_ptr< problem > to_linear_problem (const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
 Convert PyTorch tensors to liblinear format.
 
svm_node * to_svm_node (const torch::Tensor &sample)
 Convert single sample to libsvm format.
 
feature_node * to_feature_node (const torch::Tensor &sample)
 Convert single sample to liblinear format.
 
torch::Tensor from_predictions (const std::vector< double > &predictions)
 Convert predictions back to PyTorch tensor.
 
torch::Tensor from_probabilities (const std::vector< std::vector< double > > &probabilities)
 Convert probabilities back to PyTorch tensor.
 
torch::Tensor from_decision_values (const std::vector< std::vector< double > > &decision_values)
 Convert decision values back to PyTorch tensor.
 
void validate_tensors (const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
 Validate input tensors.
 
int get_n_features () const
 Get number of features from last conversion.
 
int get_n_samples () const
 Get number of samples from last conversion.
 
void cleanup ()
 Clean up all allocated memory.
 
void set_sparse_threshold (double threshold)
 Set sparse threshold (features with absolute value below this are ignored)
 
double get_sparse_threshold () const
 Get sparse threshold.
 
DataConverter ()
 Default constructor.
 
~DataConverter ()
 Destructor - cleans up allocated memory.
 
std::unique_ptr< svm_problem > to_svm_problem (const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
 Convert PyTorch tensors to libsvm format.
 
std::unique_ptr< problem > to_linear_problem (const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
 Convert PyTorch tensors to liblinear format.
 
svm_node * to_svm_node (const torch::Tensor &sample)
 Convert single sample to libsvm format.
 
feature_node * to_feature_node (const torch::Tensor &sample)
 Convert single sample to liblinear format.
 
torch::Tensor from_predictions (const std::vector< double > &predictions)
 Convert predictions back to PyTorch tensor.
 
torch::Tensor from_probabilities (const std::vector< std::vector< double > > &probabilities)
 Convert probabilities back to PyTorch tensor.
 
torch::Tensor from_decision_values (const std::vector< std::vector< double > > &decision_values)
 Convert decision values back to PyTorch tensor.
 
void validate_tensors (const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
 Validate input tensors.
 
int get_n_features () const
 Get number of features from last conversion.
 
int get_n_samples () const
 Get number of samples from last conversion.
 
+void cleanup ()
 Clean up all allocated memory.
 
void set_sparse_threshold (double threshold)
 Set sparse threshold (features with absolute value below this are ignored)
 
double get_sparse_threshold () const
 Get sparse threshold.
 
+

Detailed Description

+

Data converter between libtorch tensors and SVM library formats.

+

This class handles the conversion between PyTorch tensors and the data structures required by libsvm and liblinear libraries. It manages memory allocation and provides efficient conversion methods.

+ +

Definition at line 23 of file data_converter.hpp.

+

Constructor & Destructor Documentation

+ +

◆ DataConverter()

+ +
+
+ + + + + + + +
svm_classifier::DataConverter::DataConverter ()
+
+ +

Default constructor.

+ +

Definition at line 10 of file data_converter.cpp.

+ +
+
+ +

◆ ~DataConverter()

+ +
+
+ + + + + + + +
svm_classifier::DataConverter::~DataConverter ()
+
+ +

Destructor - cleans up allocated memory.

+ +

Definition at line 17 of file data_converter.cpp.

+ +
+
+

Member Function Documentation

+ +

◆ cleanup()

+ +
+
+ + + + + + + +
void svm_classifier::DataConverter::cleanup ()
+
+ +

Clean up all allocated memory.

+ +

Definition at line 198 of file data_converter.cpp.

+ +
+
+ +

◆ from_decision_values() [1/2]

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::DataConverter::from_decision_values (const std::vector< std::vector< double > > & decision_values)
+
+ +

Convert decision values back to PyTorch tensor.

+
Parameters
+ + +
decision_values2D vector of decision function values
+
+
+
Returns
PyTorch tensor with decision values
+ +

Definition at line 152 of file data_converter.cpp.

+ +
+
+ +

◆ from_decision_values() [2/2]

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::DataConverter::from_decision_values (const std::vector< std::vector< double > > & decision_values)
+
+ +

Convert decision values back to PyTorch tensor.

+
Parameters
+ + +
decision_values2D vector of decision function values
+
+
+
Returns
PyTorch tensor with decision values
+ +
+
+ +

◆ from_predictions() [1/2]

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::DataConverter::from_predictions (const std::vector< double > & predictions)
+
+ +

Convert predictions back to PyTorch tensor.

+
Parameters
+ + +
predictionsVector of predictions
+
+
+
Returns
PyTorch tensor with predictions
+ +

Definition at line 120 of file data_converter.cpp.

+ +
+
+ +

◆ from_predictions() [2/2]

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::DataConverter::from_predictions (const std::vector< double > & predictions)
+
+ +

Convert predictions back to PyTorch tensor.

+
Parameters
+ + +
predictionsVector of predictions
+
+
+
Returns
PyTorch tensor with predictions
+ +
+
+ +

◆ from_probabilities() [1/2]

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::DataConverter::from_probabilities (const std::vector< std::vector< double > > & probabilities)
+
+ +

Convert probabilities back to PyTorch tensor.

+
Parameters
+ + +
probabilities2D vector of class probabilities
+
+
+
Returns
PyTorch tensor with probabilities of shape (n_samples, n_classes)
+ +

Definition at line 132 of file data_converter.cpp.

+ +
+
+ +

◆ from_probabilities() [2/2]

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::DataConverter::from_probabilities (const std::vector< std::vector< double > > & probabilities)
+
+ +

Convert probabilities back to PyTorch tensor.

+
Parameters
+ + +
probabilities2D vector of class probabilities
+
+
+
Returns
PyTorch tensor with probabilities of shape (n_samples, n_classes)
+ +
+
+ +

◆ get_n_features() [1/2]

+ +
+
+ + + + + +
+ + + + + + + +
int svm_classifier::DataConverter::get_n_features () const
+
+inline
+
+ +

Get number of features from last conversion.

+
Returns
Number of features
+ +

Definition at line 100 of file data_converter.hpp.

+ +
+
+ +

◆ get_n_features() [2/2]

+ +
+
+ + + + + +
+ + + + + + + +
int svm_classifier::DataConverter::get_n_features () const
+
+inline
+
+ +

Get number of features from last conversion.

+
Returns
Number of features
+ +

Definition at line 100 of file kernel_parameters.hpp.

+ +
+
+ +

◆ get_n_samples() [1/2]

+ +
+
+ + + + + +
+ + + + + + + +
int svm_classifier::DataConverter::get_n_samples () const
+
+inline
+
+ +

Get number of samples from last conversion.

+
Returns
Number of samples
+ +

Definition at line 106 of file data_converter.hpp.

+ +
+
+ +

◆ get_n_samples() [2/2]

+ +
+
+ + + + + +
+ + + + + + + +
int svm_classifier::DataConverter::get_n_samples () const
+
+inline
+
+ +

Get number of samples from last conversion.

+
Returns
Number of samples
+ +

Definition at line 106 of file kernel_parameters.hpp.

+ +
+
+ +

◆ get_sparse_threshold() [1/2]

+ +
+
+ + + + + +
+ + + + + + + +
double svm_classifier::DataConverter::get_sparse_threshold () const
+
+inline
+
+ +

Get sparse threshold.

+
Returns
Current sparse threshold
+ +

Definition at line 123 of file data_converter.hpp.

+ +
+
+ +

◆ get_sparse_threshold() [2/2]

+ +
+
+ + + + + +
+ + + + + + + +
double svm_classifier::DataConverter::get_sparse_threshold () const
+
+inline
+
+ +

Get sparse threshold.

+
Returns
Current sparse threshold
+ +

Definition at line 123 of file kernel_parameters.hpp.

+ +
+
+ +

◆ set_sparse_threshold() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
void svm_classifier::DataConverter::set_sparse_threshold (double threshold)
+
+inline
+
+ +

Set sparse threshold (features with absolute value below this are ignored)

+
Parameters
+ + +
thresholdSparse threshold (default: 1e-8)
+
+
+ +

Definition at line 117 of file data_converter.hpp.

+ +
+
+ +

◆ set_sparse_threshold() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
void svm_classifier::DataConverter::set_sparse_threshold (double threshold)
+
+inline
+
+ +

Set sparse threshold (features with absolute value below this are ignored)

+
Parameters
+ + +
thresholdSparse threshold (default: 1e-8)
+
+
+ +

Definition at line 117 of file kernel_parameters.hpp.

+ +
+
+ +

◆ to_feature_node() [1/2]

+ +
+
+ + + + + + + + +
feature_node * svm_classifier::DataConverter::to_feature_node (const torch::Tensor & sample)
+
+ +

Convert single sample to liblinear format.

+
Parameters
+ + +
sampleFeature tensor of shape (n_features,)
+
+
+
Returns
Pointer to feature_node array
+ +

Definition at line 110 of file data_converter.cpp.

+ +
+
+ +

◆ to_feature_node() [2/2]

+ +
+
+ + + + + + + + +
feature_node * svm_classifier::DataConverter::to_feature_node (const torch::Tensor & sample)
+
+ +

Convert single sample to liblinear format.

+
Parameters
+ + +
sampleFeature tensor of shape (n_features,)
+
+
+
Returns
Pointer to feature_node array
+ +
+
+ +

◆ to_linear_problem() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
std::unique_ptr< problem > svm_classifier::DataConverter::to_linear_problem (const torch::Tensor & X,
const torch::Tensor & y = torch::Tensor() 
)
+
+ +

Convert PyTorch tensors to liblinear format.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,) - optional for prediction
+
+
+
Returns
Pointer to problem structure
+ +

Definition at line 60 of file data_converter.cpp.

+ +
+
+ +

◆ to_linear_problem() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
std::unique_ptr< problem > svm_classifier::DataConverter::to_linear_problem (const torch::Tensor & X,
const torch::Tensor & y = torch::Tensor() 
)
+
+ +

Convert PyTorch tensors to liblinear format.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,) - optional for prediction
+
+
+
Returns
Pointer to problem structure
+ +
+
+ +

◆ to_svm_node() [1/2]

+ +
+
+ + + + + + + + +
svm_node * svm_classifier::DataConverter::to_svm_node (const torch::Tensor & sample)
+
+ +

Convert single sample to libsvm format.

+
Parameters
+ + +
sampleFeature tensor of shape (n_features,)
+
+
+
Returns
Pointer to svm_node array
+ +

Definition at line 100 of file data_converter.cpp.

+ +
+
+ +

◆ to_svm_node() [2/2]

+ +
+
+ + + + + + + + +
svm_node * svm_classifier::DataConverter::to_svm_node (const torch::Tensor & sample)
+
+ +

Convert single sample to libsvm format.

+
Parameters
+ + +
sampleFeature tensor of shape (n_features,)
+
+
+
Returns
Pointer to svm_node array
+ +
+
+ +

◆ to_svm_problem() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
std::unique_ptr< svm_problem > svm_classifier::DataConverter::to_svm_problem (const torch::Tensor & X,
const torch::Tensor & y = torch::Tensor() 
)
+
+ +

Convert PyTorch tensors to libsvm format.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,) - optional for prediction
+
+
+
Returns
Pointer to svm_problem structure
+ +

Definition at line 22 of file data_converter.cpp.

+ +
+
+ +

◆ to_svm_problem() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
std::unique_ptr< svm_problem > svm_classifier::DataConverter::to_svm_problem (const torch::Tensor & X,
const torch::Tensor & y = torch::Tensor() 
)
+
+ +

Convert PyTorch tensors to libsvm format.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,) - optional for prediction
+
+
+
Returns
Pointer to svm_problem structure
+ +
+
+ +

◆ validate_tensors() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void svm_classifier::DataConverter::validate_tensors (const torch::Tensor & X,
const torch::Tensor & y = torch::Tensor() 
)
+
+ +

Validate input tensors.

+
Parameters
+ + + +
XFeature tensor
yTarget tensor (optional)
+
+
+
Exceptions
+ + +
std::invalid_argumentif tensors are invalid
+
+
+ +

Definition at line 172 of file data_converter.cpp.

+ +
+
+ +

◆ validate_tensors() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void svm_classifier::DataConverter::validate_tensors (const torch::Tensor & X,
const torch::Tensor & y = torch::Tensor() 
)
+
+ +

Validate input tensors.

+
Parameters
+ + + +
XFeature tensor
yTarget tensor (optional)
+
+
+
Exceptions
+ + +
std::invalid_argumentif tensors are invalid
+
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/classsvm__classifier_1_1MulticlassStrategyBase-members.html b/classsvm__classifier_1_1MulticlassStrategyBase-members.html new file mode 100644 index 0000000..2203727 --- /dev/null +++ b/classsvm__classifier_1_1MulticlassStrategyBase-members.html @@ -0,0 +1,100 @@ + + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
svm_classifier::MulticlassStrategyBase Member List
+
+
+ +

This is the complete list of members for svm_classifier::MulticlassStrategyBase, including all inherited members.

+ + + + + + + + + + + + +
classes_svm_classifier::MulticlassStrategyBaseprotected
decision_function(const torch::Tensor &X, DataConverter &converter)=0svm_classifier::MulticlassStrategyBasepure virtual
fit(const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter)=0svm_classifier::MulticlassStrategyBasepure virtual
get_classes() const =0svm_classifier::MulticlassStrategyBasepure virtual
get_n_classes() const =0svm_classifier::MulticlassStrategyBasepure virtual
get_strategy_type() const =0svm_classifier::MulticlassStrategyBasepure virtual
is_trained_svm_classifier::MulticlassStrategyBaseprotected
predict(const torch::Tensor &X, DataConverter &converter)=0svm_classifier::MulticlassStrategyBasepure virtual
predict_proba(const torch::Tensor &X, DataConverter &converter)=0svm_classifier::MulticlassStrategyBasepure virtual
supports_probability() const =0svm_classifier::MulticlassStrategyBasepure virtual
~MulticlassStrategyBase()=defaultsvm_classifier::MulticlassStrategyBasevirtual
+ + + + diff --git a/classsvm__classifier_1_1MulticlassStrategyBase.html b/classsvm__classifier_1_1MulticlassStrategyBase.html new file mode 100644 index 0000000..5056f6d --- /dev/null +++ b/classsvm__classifier_1_1MulticlassStrategyBase.html @@ -0,0 +1,535 @@ + + + + + + + +SVM Classifier C++: svm_classifier::MulticlassStrategyBase Class Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+ +
svm_classifier::MulticlassStrategyBase Class Referenceabstract
+
+
+ +

Abstract base class for multiclass classification strategies. + More...

+ +

#include <multiclass_strategy.hpp>

+
+Inheritance diagram for svm_classifier::MulticlassStrategyBase:
+
+
Inheritance graph
+ + + + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

+virtual ~MulticlassStrategyBase ()=default
 Virtual destructor.
 
virtual TrainingMetrics fit (const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter)=0
 Train the multiclass classifier.
 
virtual std::vector< int > predict (const torch::Tensor &X, DataConverter &converter)=0
 Predict class labels.
 
virtual std::vector< std::vector< double > > predict_proba (const torch::Tensor &X, DataConverter &converter)=0
 Predict class probabilities.
 
virtual std::vector< std::vector< double > > decision_function (const torch::Tensor &X, DataConverter &converter)=0
 Get decision function values.
 
virtual std::vector< int > get_classes () const =0
 Get unique class labels.
 
virtual bool supports_probability () const =0
 Check if the model supports probability prediction.
 
virtual int get_n_classes () const =0
 Get number of classes.
 
virtual MulticlassStrategy get_strategy_type () const =0
 Get strategy type.
 
+ + + + + + + +

+Protected Attributes

std::vector< int > classes_
 Unique class labels.
 
bool is_trained_ = false
 Whether the model is trained.
 
+

Detailed Description

+

Abstract base class for multiclass classification strategies.

+ +

Definition at line 20 of file multiclass_strategy.hpp.

+

Member Function Documentation

+ +

◆ decision_function()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual std::vector< std::vector< double > > svm_classifier::MulticlassStrategyBase::decision_function (const torch::Tensor & X,
DataConverterconverter 
)
+
+pure virtual
+
+ +

Get decision function values.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Decision function values
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+ +

◆ fit()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual TrainingMetrics svm_classifier::MulticlassStrategyBase::fit (const torch::Tensor & X,
const torch::Tensor & y,
const KernelParameters & params,
DataConverterconverter 
)
+
+pure virtual
+
+ +

Train the multiclass classifier.

+
Parameters
+ + + + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,)
paramsKernel parameters
converterData converter instance
+
+
+
Returns
Training metrics
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+ +

◆ get_classes()

+ +
+
+ + + + + +
+ + + + + + + +
virtual std::vector< int > svm_classifier::MulticlassStrategyBase::get_classes () const
+
+pure virtual
+
+ +

Get unique class labels.

+
Returns
Vector of unique class labels
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+ +

◆ get_n_classes()

+ +
+
+ + + + + +
+ + + + + + + +
virtual int svm_classifier::MulticlassStrategyBase::get_n_classes () const
+
+pure virtual
+
+ +

Get number of classes.

+
Returns
Number of classes
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+ +

◆ get_strategy_type()

+ +
+
+ + + + + +
+ + + + + + + +
virtual MulticlassStrategy svm_classifier::MulticlassStrategyBase::get_strategy_type () const
+
+pure virtual
+
+ +

Get strategy type.

+
Returns
Multiclass strategy type
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+ +

◆ predict()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual std::vector< int > svm_classifier::MulticlassStrategyBase::predict (const torch::Tensor & X,
DataConverterconverter 
)
+
+pure virtual
+
+ +

Predict class labels.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Predicted class labels
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+ +

◆ predict_proba()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual std::vector< std::vector< double > > svm_classifier::MulticlassStrategyBase::predict_proba (const torch::Tensor & X,
DataConverterconverter 
)
+
+pure virtual
+
+ +

Predict class probabilities.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Class probabilities for each sample
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+ +

◆ supports_probability()

+ +
+
+ + + + + +
+ + + + + + + +
virtual bool svm_classifier::MulticlassStrategyBase::supports_probability () const
+
+pure virtual
+
+ +

Check if the model supports probability prediction.

+
Returns
True if probabilities are supported
+ +

Implemented in svm_classifier::OneVsRestStrategy, and svm_classifier::OneVsOneStrategy.

+ +
+
+

Member Data Documentation

+ +

◆ classes_

+ +
+
+ + + + + +
+ + + + +
std::vector<int> svm_classifier::MulticlassStrategyBase::classes_
+
+protected
+
+ +

Unique class labels.

+ +

Definition at line 92 of file multiclass_strategy.hpp.

+ +
+
+ +

◆ is_trained_

+ +
+
+ + + + + +
+ + + + +
bool svm_classifier::MulticlassStrategyBase::is_trained_ = false
+
+protected
+
+ +

Whether the model is trained.

+ +

Definition at line 93 of file multiclass_strategy.hpp.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.map b/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.map new file mode 100644 index 0000000..8daac1c --- /dev/null +++ b/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.map @@ -0,0 +1,7 @@ + + + + + + + diff --git a/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.md5 b/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.md5 new file mode 100644 index 0000000..eca2491 --- /dev/null +++ b/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.md5 @@ -0,0 +1 @@ +528c9ce273deafae79516be82a187c40 \ No newline at end of file diff --git a/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.png b/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.png new file mode 100644 index 0000000..13d0b86 Binary files /dev/null and b/classsvm__classifier_1_1MulticlassStrategyBase__inherit__graph.png differ diff --git a/classsvm__classifier_1_1OneVsOneStrategy-members.html b/classsvm__classifier_1_1OneVsOneStrategy-members.html new file mode 100644 index 0000000..34b4d23 --- /dev/null +++ b/classsvm__classifier_1_1OneVsOneStrategy-members.html @@ -0,0 +1,102 @@ + + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
svm_classifier::OneVsOneStrategy Member List
+
+
+ +

This is the complete list of members for svm_classifier::OneVsOneStrategy, including all inherited members.

+ + + + + + + + + + + + + + +
classes_svm_classifier::MulticlassStrategyBaseprotected
decision_function(const torch::Tensor &X, DataConverter &converter) overridesvm_classifier::OneVsOneStrategyvirtual
fit(const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter) overridesvm_classifier::OneVsOneStrategyvirtual
get_classes() const overridesvm_classifier::OneVsOneStrategyinlinevirtual
get_n_classes() const overridesvm_classifier::OneVsOneStrategyinlinevirtual
get_strategy_type() const overridesvm_classifier::OneVsOneStrategyinlinevirtual
is_trained_svm_classifier::MulticlassStrategyBaseprotected
OneVsOneStrategy()svm_classifier::OneVsOneStrategy
predict(const torch::Tensor &X, DataConverter &converter) overridesvm_classifier::OneVsOneStrategyvirtual
predict_proba(const torch::Tensor &X, DataConverter &converter) overridesvm_classifier::OneVsOneStrategyvirtual
supports_probability() const overridesvm_classifier::OneVsOneStrategyvirtual
~MulticlassStrategyBase()=defaultsvm_classifier::MulticlassStrategyBasevirtual
~OneVsOneStrategy() overridesvm_classifier::OneVsOneStrategy
+ + + + diff --git a/classsvm__classifier_1_1OneVsOneStrategy.html b/classsvm__classifier_1_1OneVsOneStrategy.html new file mode 100644 index 0000000..1d5babf --- /dev/null +++ b/classsvm__classifier_1_1OneVsOneStrategy.html @@ -0,0 +1,505 @@ + + + + + + + +SVM Classifier C++: svm_classifier::OneVsOneStrategy Class Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+ +
svm_classifier::OneVsOneStrategy Class Reference
+
+
+ +

One-vs-One (OvO) multiclass strategy. + More...

+ +

#include <multiclass_strategy.hpp>

+
+Inheritance diagram for svm_classifier::OneVsOneStrategy:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for svm_classifier::OneVsOneStrategy:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

OneVsOneStrategy ()
 Constructor.
 
~OneVsOneStrategy () override
 Destructor.
 
TrainingMetrics fit (const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter) override
 Train the multiclass classifier.
 
std::vector< int > predict (const torch::Tensor &X, DataConverter &converter) override
 Predict class labels.
 
std::vector< std::vector< double > > predict_proba (const torch::Tensor &X, DataConverter &converter) override
 Predict class probabilities.
 
std::vector< std::vector< double > > decision_function (const torch::Tensor &X, DataConverter &converter) override
 Get decision function values.
 
std::vector< int > get_classes () const override
 Get unique class labels.
 
bool supports_probability () const override
 Check if the model supports probability prediction.
 
int get_n_classes () const override
 Get number of classes.
 
MulticlassStrategy get_strategy_type () const override
 Get strategy type.
 
- Public Member Functions inherited from svm_classifier::MulticlassStrategyBase
+virtual ~MulticlassStrategyBase ()=default
 Virtual destructor.
 
+ + + + + + + + +

+Additional Inherited Members

- Protected Attributes inherited from svm_classifier::MulticlassStrategyBase
std::vector< int > classes_
 Unique class labels.
 
bool is_trained_ = false
 Whether the model is trained.
 
+

Detailed Description

+

One-vs-One (OvO) multiclass strategy.

+ +

Definition at line 171 of file multiclass_strategy.hpp.

+

Member Function Documentation

+ +

◆ decision_function()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::vector< std::vector< double > > svm_classifier::OneVsOneStrategy::decision_function (const torch::Tensor & X,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Get decision function values.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Decision function values
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ fit()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrainingMetrics svm_classifier::OneVsOneStrategy::fit (const torch::Tensor & X,
const torch::Tensor & y,
const KernelParameters & params,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Train the multiclass classifier.

+
Parameters
+ + + + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,)
paramsKernel parameters
converterData converter instance
+
+
+
Returns
Training metrics
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ get_classes()

+ +
+
+ + + + + +
+ + + + + + + +
std::vector< int > svm_classifier::OneVsOneStrategy::get_classes () const
+
+inlineoverridevirtual
+
+ +

Get unique class labels.

+
Returns
Vector of unique class labels
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +

Definition at line 197 of file multiclass_strategy.hpp.

+ +
+
+ +

◆ get_n_classes()

+ +
+
+ + + + + +
+ + + + + + + +
int svm_classifier::OneVsOneStrategy::get_n_classes () const
+
+inlineoverridevirtual
+
+ +

Get number of classes.

+
Returns
Number of classes
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +

Definition at line 201 of file multiclass_strategy.hpp.

+ +
+
+ +

◆ get_strategy_type()

+ +
+
+ + + + + +
+ + + + + + + +
MulticlassStrategy svm_classifier::OneVsOneStrategy::get_strategy_type () const
+
+inlineoverridevirtual
+
+ +

Get strategy type.

+
Returns
Multiclass strategy type
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +

Definition at line 203 of file multiclass_strategy.hpp.

+ +
+
+ +

◆ predict()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::vector< int > svm_classifier::OneVsOneStrategy::predict (const torch::Tensor & X,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Predict class labels.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Predicted class labels
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ predict_proba()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::vector< std::vector< double > > svm_classifier::OneVsOneStrategy::predict_proba (const torch::Tensor & X,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Predict class probabilities.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Class probabilities for each sample
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ supports_probability()

+ +
+
+ + + + + +
+ + + + + + + +
bool svm_classifier::OneVsOneStrategy::supports_probability () const
+
+overridevirtual
+
+ +

Check if the model supports probability prediction.

+
Returns
True if probabilities are supported
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.map b/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.map new file mode 100644 index 0000000..edcc92e --- /dev/null +++ b/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.md5 b/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.md5 new file mode 100644 index 0000000..5410a52 --- /dev/null +++ b/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.md5 @@ -0,0 +1 @@ +7b2745aed1351f8dbfbc5d248f9ff666 \ No newline at end of file diff --git a/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.png b/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.png new file mode 100644 index 0000000..e8720eb Binary files /dev/null and b/classsvm__classifier_1_1OneVsOneStrategy__coll__graph.png differ diff --git a/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.map b/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.map new file mode 100644 index 0000000..edcc92e --- /dev/null +++ b/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.md5 b/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.md5 new file mode 100644 index 0000000..5410a52 --- /dev/null +++ b/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.md5 @@ -0,0 +1 @@ +7b2745aed1351f8dbfbc5d248f9ff666 \ No newline at end of file diff --git a/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.png b/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.png new file mode 100644 index 0000000..e8720eb Binary files /dev/null and b/classsvm__classifier_1_1OneVsOneStrategy__inherit__graph.png differ diff --git a/classsvm__classifier_1_1OneVsRestStrategy-members.html b/classsvm__classifier_1_1OneVsRestStrategy-members.html new file mode 100644 index 0000000..e2a1882 --- /dev/null +++ b/classsvm__classifier_1_1OneVsRestStrategy-members.html @@ -0,0 +1,102 @@ + + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
svm_classifier::OneVsRestStrategy Member List
+
+
+ +

This is the complete list of members for svm_classifier::OneVsRestStrategy, including all inherited members.

+ + + + + + + + + + + + + + +
classes_svm_classifier::MulticlassStrategyBaseprotected
decision_function(const torch::Tensor &X, DataConverter &converter) overridesvm_classifier::OneVsRestStrategyvirtual
fit(const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter) overridesvm_classifier::OneVsRestStrategyvirtual
get_classes() const overridesvm_classifier::OneVsRestStrategyinlinevirtual
get_n_classes() const overridesvm_classifier::OneVsRestStrategyinlinevirtual
get_strategy_type() const overridesvm_classifier::OneVsRestStrategyinlinevirtual
is_trained_svm_classifier::MulticlassStrategyBaseprotected
OneVsRestStrategy()svm_classifier::OneVsRestStrategy
predict(const torch::Tensor &X, DataConverter &converter) overridesvm_classifier::OneVsRestStrategyvirtual
predict_proba(const torch::Tensor &X, DataConverter &converter) overridesvm_classifier::OneVsRestStrategyvirtual
supports_probability() const overridesvm_classifier::OneVsRestStrategyvirtual
~MulticlassStrategyBase()=defaultsvm_classifier::MulticlassStrategyBasevirtual
~OneVsRestStrategy() overridesvm_classifier::OneVsRestStrategy
+ + + + diff --git a/classsvm__classifier_1_1OneVsRestStrategy.html b/classsvm__classifier_1_1OneVsRestStrategy.html new file mode 100644 index 0000000..6c0ed03 --- /dev/null +++ b/classsvm__classifier_1_1OneVsRestStrategy.html @@ -0,0 +1,505 @@ + + + + + + + +SVM Classifier C++: svm_classifier::OneVsRestStrategy Class Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+ +
svm_classifier::OneVsRestStrategy Class Reference
+
+
+ +

One-vs-Rest (OvR) multiclass strategy. + More...

+ +

#include <multiclass_strategy.hpp>

+
+Inheritance diagram for svm_classifier::OneVsRestStrategy:
+
+
Inheritance graph
+ + + + + +
[legend]
+
+Collaboration diagram for svm_classifier::OneVsRestStrategy:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

OneVsRestStrategy ()
 Constructor.
 
~OneVsRestStrategy () override
 Destructor.
 
TrainingMetrics fit (const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter) override
 Train the multiclass classifier.
 
std::vector< int > predict (const torch::Tensor &X, DataConverter &converter) override
 Predict class labels.
 
std::vector< std::vector< double > > predict_proba (const torch::Tensor &X, DataConverter &converter) override
 Predict class probabilities.
 
std::vector< std::vector< double > > decision_function (const torch::Tensor &X, DataConverter &converter) override
 Get decision function values.
 
std::vector< int > get_classes () const override
 Get unique class labels.
 
bool supports_probability () const override
 Check if the model supports probability prediction.
 
int get_n_classes () const override
 Get number of classes.
 
MulticlassStrategy get_strategy_type () const override
 Get strategy type.
 
- Public Member Functions inherited from svm_classifier::MulticlassStrategyBase
+virtual ~MulticlassStrategyBase ()=default
 Virtual destructor.
 
+ + + + + + + + +

+Additional Inherited Members

- Protected Attributes inherited from svm_classifier::MulticlassStrategyBase
std::vector< int > classes_
 Unique class labels.
 
bool is_trained_ = false
 Whether the model is trained.
 
+

Detailed Description

+

One-vs-Rest (OvR) multiclass strategy.

+ +

Definition at line 99 of file multiclass_strategy.hpp.

+

Member Function Documentation

+ +

◆ decision_function()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::vector< std::vector< double > > svm_classifier::OneVsRestStrategy::decision_function (const torch::Tensor & X,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Get decision function values.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Decision function values
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ fit()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrainingMetrics svm_classifier::OneVsRestStrategy::fit (const torch::Tensor & X,
const torch::Tensor & y,
const KernelParameters & params,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Train the multiclass classifier.

+
Parameters
+ + + + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,)
paramsKernel parameters
converterData converter instance
+
+
+
Returns
Training metrics
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ get_classes()

+ +
+
+ + + + + +
+ + + + + + + +
std::vector< int > svm_classifier::OneVsRestStrategy::get_classes () const
+
+inlineoverridevirtual
+
+ +

Get unique class labels.

+
Returns
Vector of unique class labels
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +

Definition at line 125 of file multiclass_strategy.hpp.

+ +
+
+ +

◆ get_n_classes()

+ +
+
+ + + + + +
+ + + + + + + +
int svm_classifier::OneVsRestStrategy::get_n_classes () const
+
+inlineoverridevirtual
+
+ +

Get number of classes.

+
Returns
Number of classes
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +

Definition at line 129 of file multiclass_strategy.hpp.

+ +
+
+ +

◆ get_strategy_type()

+ +
+
+ + + + + +
+ + + + + + + +
MulticlassStrategy svm_classifier::OneVsRestStrategy::get_strategy_type () const
+
+inlineoverridevirtual
+
+ +

Get strategy type.

+
Returns
Multiclass strategy type
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +

Definition at line 131 of file multiclass_strategy.hpp.

+ +
+
+ +

◆ predict()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::vector< int > svm_classifier::OneVsRestStrategy::predict (const torch::Tensor & X,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Predict class labels.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Predicted class labels
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ predict_proba()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::vector< std::vector< double > > svm_classifier::OneVsRestStrategy::predict_proba (const torch::Tensor & X,
DataConverterconverter 
)
+
+overridevirtual
+
+ +

Predict class probabilities.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
converterData converter instance
+
+
+
Returns
Class probabilities for each sample
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+ +

◆ supports_probability()

+ +
+
+ + + + + +
+ + + + + + + +
bool svm_classifier::OneVsRestStrategy::supports_probability () const
+
+overridevirtual
+
+ +

Check if the model supports probability prediction.

+
Returns
True if probabilities are supported
+ +

Implements svm_classifier::MulticlassStrategyBase.

+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.map b/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.map new file mode 100644 index 0000000..c1f169b --- /dev/null +++ b/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.md5 b/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.md5 new file mode 100644 index 0000000..57d22b8 --- /dev/null +++ b/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.md5 @@ -0,0 +1 @@ +77f554e6e02c3b0e2a64fa96a85301d2 \ No newline at end of file diff --git a/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.png b/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.png new file mode 100644 index 0000000..fc930ec Binary files /dev/null and b/classsvm__classifier_1_1OneVsRestStrategy__coll__graph.png differ diff --git a/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.map b/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.map new file mode 100644 index 0000000..c1f169b --- /dev/null +++ b/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.md5 b/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.md5 new file mode 100644 index 0000000..57d22b8 --- /dev/null +++ b/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.md5 @@ -0,0 +1 @@ +77f554e6e02c3b0e2a64fa96a85301d2 \ No newline at end of file diff --git a/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.png b/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.png new file mode 100644 index 0000000..fc930ec Binary files /dev/null and b/classsvm__classifier_1_1OneVsRestStrategy__inherit__graph.png differ diff --git a/classsvm__classifier_1_1SVMClassifier-members.html b/classsvm__classifier_1_1SVMClassifier-members.html new file mode 100644 index 0000000..356eb67 --- /dev/null +++ b/classsvm__classifier_1_1SVMClassifier-members.html @@ -0,0 +1,120 @@ + + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
svm_classifier::SVMClassifier Member List
+
+
+ +

This is the complete list of members for svm_classifier::SVMClassifier, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
cross_validate(const torch::Tensor &X, const torch::Tensor &y, int cv=5)svm_classifier::SVMClassifier
decision_function(const torch::Tensor &X)svm_classifier::SVMClassifier
evaluate(const torch::Tensor &X, const torch::Tensor &y_true)svm_classifier::SVMClassifier
fit(const torch::Tensor &X, const torch::Tensor &y)svm_classifier::SVMClassifier
get_classes() constsvm_classifier::SVMClassifier
get_feature_importance() constsvm_classifier::SVMClassifier
get_kernel_type() constsvm_classifier::SVMClassifierinline
get_multiclass_strategy() constsvm_classifier::SVMClassifierinline
get_n_classes() constsvm_classifier::SVMClassifier
get_n_features() constsvm_classifier::SVMClassifierinline
get_parameters() constsvm_classifier::SVMClassifier
get_svm_library() constsvm_classifier::SVMClassifierinline
get_training_metrics() constsvm_classifier::SVMClassifierinline
grid_search(const torch::Tensor &X, const torch::Tensor &y, const nlohmann::json &param_grid, int cv=5)svm_classifier::SVMClassifier
is_fitted() constsvm_classifier::SVMClassifierinline
load_model(const std::string &filename)svm_classifier::SVMClassifier
operator=(const SVMClassifier &)=deletesvm_classifier::SVMClassifier
operator=(SVMClassifier &&) noexceptsvm_classifier::SVMClassifier
predict(const torch::Tensor &X)svm_classifier::SVMClassifier
predict_proba(const torch::Tensor &X)svm_classifier::SVMClassifier
reset()svm_classifier::SVMClassifier
save_model(const std::string &filename) constsvm_classifier::SVMClassifier
score(const torch::Tensor &X, const torch::Tensor &y_true)svm_classifier::SVMClassifier
set_parameters(const nlohmann::json &config)svm_classifier::SVMClassifier
supports_probability() constsvm_classifier::SVMClassifier
SVMClassifier()svm_classifier::SVMClassifier
SVMClassifier(const nlohmann::json &config)svm_classifier::SVMClassifierexplicit
SVMClassifier(KernelType kernel, double C=1.0, MulticlassStrategy multiclass_strategy=MulticlassStrategy::ONE_VS_REST)svm_classifier::SVMClassifier
SVMClassifier(const SVMClassifier &)=deletesvm_classifier::SVMClassifier
SVMClassifier(SVMClassifier &&) noexceptsvm_classifier::SVMClassifier
~SVMClassifier()svm_classifier::SVMClassifier
+ + + + diff --git a/classsvm__classifier_1_1SVMClassifier.html b/classsvm__classifier_1_1SVMClassifier.html new file mode 100644 index 0000000..8e62777 --- /dev/null +++ b/classsvm__classifier_1_1SVMClassifier.html @@ -0,0 +1,991 @@ + + + + + + + +SVM Classifier C++: svm_classifier::SVMClassifier Class Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+ +
svm_classifier::SVMClassifier Class Reference
+
+
+ +

Support Vector Machine Classifier with scikit-learn compatible API. + More...

+ +

#include <svm_classifier.hpp>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

SVMClassifier ()
 Default constructor with default parameters.
 
 SVMClassifier (const nlohmann::json &config)
 Constructor with JSON parameters.
 
 SVMClassifier (KernelType kernel, double C=1.0, MulticlassStrategy multiclass_strategy=MulticlassStrategy::ONE_VS_REST)
 Constructor with explicit parameters.
 
~SVMClassifier ()
 Destructor.
 
SVMClassifier (const SVMClassifier &)=delete
 Copy constructor (deleted - models are not copyable)
 
+SVMClassifieroperator= (const SVMClassifier &)=delete
 Copy assignment (deleted - models are not copyable)
 
SVMClassifier (SVMClassifier &&) noexcept
 Move constructor.
 
+SVMClassifieroperator= (SVMClassifier &&) noexcept
 Move assignment.
 
TrainingMetrics fit (const torch::Tensor &X, const torch::Tensor &y)
 Train the SVM classifier.
 
torch::Tensor predict (const torch::Tensor &X)
 Predict class labels for samples.
 
torch::Tensor predict_proba (const torch::Tensor &X)
 Predict class probabilities for samples.
 
torch::Tensor decision_function (const torch::Tensor &X)
 Get decision function values.
 
double score (const torch::Tensor &X, const torch::Tensor &y_true)
 Calculate accuracy score on test data.
 
EvaluationMetrics evaluate (const torch::Tensor &X, const torch::Tensor &y_true)
 Calculate detailed evaluation metrics.
 
void set_parameters (const nlohmann::json &config)
 Set parameters from JSON configuration.
 
nlohmann::json get_parameters () const
 Get current parameters as JSON.
 
bool is_fitted () const
 Check if the model is fitted/trained.
 
int get_n_classes () const
 Get the number of classes.
 
std::vector< int > get_classes () const
 Get unique class labels.
 
int get_n_features () const
 Get the number of features.
 
TrainingMetrics get_training_metrics () const
 Get training metrics from last fit.
 
bool supports_probability () const
 Check if the current model supports probability prediction.
 
void save_model (const std::string &filename) const
 Save model to file.
 
void load_model (const std::string &filename)
 Load model from file.
 
KernelType get_kernel_type () const
 Get kernel type.
 
MulticlassStrategy get_multiclass_strategy () const
 Get multiclass strategy.
 
SVMLibrary get_svm_library () const
 Get SVM library being used.
 
std::vector< double > cross_validate (const torch::Tensor &X, const torch::Tensor &y, int cv=5)
 Perform cross-validation.
 
nlohmann::json grid_search (const torch::Tensor &X, const torch::Tensor &y, const nlohmann::json &param_grid, int cv=5)
 Find optimal hyperparameters using grid search.
 
torch::Tensor get_feature_importance () const
 Get feature importance (for linear kernels only)
 
+void reset ()
 Reset the classifier (clear trained model)
 
+

Detailed Description

+

Support Vector Machine Classifier with scikit-learn compatible API.

+

This class provides a unified interface for SVM classification using both liblinear (for linear kernels) and libsvm (for non-linear kernels). It supports multiclass classification through One-vs-Rest and One-vs-One strategies.

+ +

Definition at line 21 of file svm_classifier.hpp.

+

Constructor & Destructor Documentation

+ +

◆ SVMClassifier() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
svm_classifier::SVMClassifier::SVMClassifier (const nlohmann::json & config)
+
+explicit
+
+ +

Constructor with JSON parameters.

+
Parameters
+ + +
configJSON configuration object
+
+
+ +
+
+ +

◆ SVMClassifier() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
svm_classifier::SVMClassifier::SVMClassifier (KernelType kernel,
double C = 1.0,
MulticlassStrategy multiclass_strategy = MulticlassStrategy::ONE_VS_REST 
)
+
+ +

Constructor with explicit parameters.

+
Parameters
+ + + + +
kernelKernel type
CRegularization parameter
multiclass_strategyMulticlass strategy
+
+
+ +
+
+

Member Function Documentation

+ +

◆ cross_validate()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
std::vector< double > svm_classifier::SVMClassifier::cross_validate (const torch::Tensor & X,
const torch::Tensor & y,
int cv = 5 
)
+
+ +

Perform cross-validation.

+
Parameters
+ + + + +
XFeature tensor
yTarget tensor
cvNumber of folds (default: 5)
+
+
+
Returns
Cross-validation scores for each fold
+ +
+
+ +

◆ decision_function()

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::SVMClassifier::decision_function (const torch::Tensor & X)
+
+ +

Get decision function values.

+
Parameters
+ + +
XFeature tensor of shape (n_samples, n_features)
+
+
+
Returns
Tensor with decision function values
+
Exceptions
+ + +
std::runtime_errorif model is not fitted
+
+
+ +
+
+ +

◆ evaluate()

+ +
+
+ + + + + + + + + + + + + + + + + + +
EvaluationMetrics svm_classifier::SVMClassifier::evaluate (const torch::Tensor & X,
const torch::Tensor & y_true 
)
+
+ +

Calculate detailed evaluation metrics.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
y_trueTrue labels tensor of shape (n_samples,)
+
+
+
Returns
Evaluation metrics including precision, recall, F1-score
+ +
+
+ +

◆ fit()

+ +
+
+ + + + + + + + + + + + + + + + + + +
TrainingMetrics svm_classifier::SVMClassifier::fit (const torch::Tensor & X,
const torch::Tensor & y 
)
+
+ +

Train the SVM classifier.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
yTarget tensor of shape (n_samples,) with class labels
+
+
+
Returns
Training metrics
+
Exceptions
+ + + +
std::invalid_argumentif input data is invalid
std::runtime_errorif training fails
+
+
+ +
+
+ +

◆ get_classes()

+ +
+
+ + + + + + + +
std::vector< int > svm_classifier::SVMClassifier::get_classes () const
+
+ +

Get unique class labels.

+
Returns
Vector of unique class labels
+ +
+
+ +

◆ get_feature_importance()

+ +
+
+ + + + + + + +
torch::Tensor svm_classifier::SVMClassifier::get_feature_importance () const
+
+ +

Get feature importance (for linear kernels only)

+
Returns
Tensor with feature weights/importance
+
Exceptions
+ + +
std::runtime_errorif not supported for current kernel
+
+
+ +
+
+ +

◆ get_kernel_type()

+ +
+
+ + + + + +
+ + + + + + + +
KernelType svm_classifier::SVMClassifier::get_kernel_type () const
+
+inline
+
+ +

Get kernel type.

+
Returns
Current kernel type
+ +

Definition at line 187 of file svm_classifier.hpp.

+ +
+
+ +

◆ get_multiclass_strategy()

+ +
+
+ + + + + +
+ + + + + + + +
MulticlassStrategy svm_classifier::SVMClassifier::get_multiclass_strategy () const
+
+inline
+
+ +

Get multiclass strategy.

+
Returns
Current multiclass strategy
+ +

Definition at line 193 of file svm_classifier.hpp.

+ +
+
+ +

◆ get_n_classes()

+ +
+
+ + + + + + + +
int svm_classifier::SVMClassifier::get_n_classes () const
+
+ +

Get the number of classes.

+
Returns
Number of classes (0 if not fitted)
+ +
+
+ +

◆ get_n_features()

+ +
+
+ + + + + +
+ + + + + + + +
int svm_classifier::SVMClassifier::get_n_features () const
+
+inline
+
+ +

Get the number of features.

+
Returns
Number of features (0 if not fitted)
+ +

Definition at line 155 of file svm_classifier.hpp.

+ +
+
+ +

◆ get_parameters()

+ +
+
+ + + + + + + +
nlohmann::json svm_classifier::SVMClassifier::get_parameters () const
+
+ +

Get current parameters as JSON.

+
Returns
JSON object with current parameters
+ +
+
+ +

◆ get_svm_library()

+ +
+
+ + + + + +
+ + + + + + + +
SVMLibrary svm_classifier::SVMClassifier::get_svm_library () const
+
+inline
+
+ +

Get SVM library being used.

+
Returns
SVM library type
+ +

Definition at line 199 of file svm_classifier.hpp.

+ +
+
+ +

◆ get_training_metrics()

+ +
+
+ + + + + +
+ + + + + + + +
TrainingMetrics svm_classifier::SVMClassifier::get_training_metrics () const
+
+inline
+
+ +

Get training metrics from last fit.

+
Returns
Training metrics
+ +

Definition at line 161 of file svm_classifier.hpp.

+ +
+
+ +

◆ grid_search()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
nlohmann::json svm_classifier::SVMClassifier::grid_search (const torch::Tensor & X,
const torch::Tensor & y,
const nlohmann::json & param_grid,
int cv = 5 
)
+
+ +

Find optimal hyperparameters using grid search.

+
Parameters
+ + + + + +
XFeature tensor
yTarget tensor
param_gridJSON object with parameter grid
cvNumber of cross-validation folds
+
+
+
Returns
JSON object with best parameters and score
+ +
+
+ +

◆ is_fitted()

+ +
+
+ + + + + +
+ + + + + + + +
bool svm_classifier::SVMClassifier::is_fitted () const
+
+inline
+
+ +

Check if the model is fitted/trained.

+
Returns
True if model is fitted
+ +

Definition at line 137 of file svm_classifier.hpp.

+ +
+
+ +

◆ load_model()

+ +
+
+ + + + + + + + +
void svm_classifier::SVMClassifier::load_model (const std::string & filename)
+
+ +

Load model from file.

+
Parameters
+ + +
filenamePath to load the model from
+
+
+
Exceptions
+ + +
std::runtime_errorif loading fails
+
+
+ +
+
+ +

◆ predict()

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::SVMClassifier::predict (const torch::Tensor & X)
+
+ +

Predict class labels for samples.

+
Parameters
+ + +
XFeature tensor of shape (n_samples, n_features)
+
+
+
Returns
Tensor of predicted class labels
+
Exceptions
+ + +
std::runtime_errorif model is not fitted
+
+
+ +
+
+ +

◆ predict_proba()

+ +
+
+ + + + + + + + +
torch::Tensor svm_classifier::SVMClassifier::predict_proba (const torch::Tensor & X)
+
+ +

Predict class probabilities for samples.

+
Parameters
+ + +
XFeature tensor of shape (n_samples, n_features)
+
+
+
Returns
Tensor of shape (n_samples, n_classes) with class probabilities
+
Exceptions
+ + +
std::runtime_errorif model is not fitted or doesn't support probabilities
+
+
+ +
+
+ +

◆ save_model()

+ +
+
+ + + + + + + + +
void svm_classifier::SVMClassifier::save_model (const std::string & filename) const
+
+ +

Save model to file.

+
Parameters
+ + +
filenamePath to save the model
+
+
+
Exceptions
+ + +
std::runtime_errorif saving fails
+
+
+ +
+
+ +

◆ score()

+ +
+
+ + + + + + + + + + + + + + + + + + +
double svm_classifier::SVMClassifier::score (const torch::Tensor & X,
const torch::Tensor & y_true 
)
+
+ +

Calculate accuracy score on test data.

+
Parameters
+ + + +
XFeature tensor of shape (n_samples, n_features)
y_trueTrue labels tensor of shape (n_samples,)
+
+
+
Returns
Accuracy score (fraction of correctly predicted samples)
+
Exceptions
+ + +
std::runtime_errorif model is not fitted
+
+
+ +
+
+ +

◆ set_parameters()

+ +
+
+ + + + + + + + +
void svm_classifier::SVMClassifier::set_parameters (const nlohmann::json & config)
+
+ +

Set parameters from JSON configuration.

+
Parameters
+ + +
configJSON configuration object
+
+
+
Exceptions
+ + +
std::invalid_argumentif parameters are invalid
+
+
+ +
+
+ +

◆ supports_probability()

+ +
+
+ + + + + + + +
bool svm_classifier::SVMClassifier::supports_probability () const
+
+ +

Check if the current model supports probability prediction.

+
Returns
True if probabilities are supported
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/closed.png b/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/closed.png differ diff --git a/data__converter_8cpp_source.html b/data__converter_8cpp_source.html new file mode 100644 index 0000000..f4369e8 --- /dev/null +++ b/data__converter_8cpp_source.html @@ -0,0 +1,502 @@ + + + + + + + +SVM Classifier C++: src/data_converter.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
data_converter.cpp
+
+
+
1#include "svm_classifier/data_converter.hpp"
+
2#include "svm.h" // libsvm
+
3#include "linear.h" // liblinear
+
4#include <stdexcept>
+
5#include <iostream>
+
6#include <cmath>
+
7
+
8namespace svm_classifier {
+
9
+
+ +
11 : n_features_(0)
+
12 , n_samples_(0)
+
13 , sparse_threshold_(1e-8)
+
14 {
+
15 }
+
+
16
+
+ +
18 {
+
19 cleanup();
+
20 }
+
+
21
+
+
22 std::unique_ptr<svm_problem> DataConverter::to_svm_problem(const torch::Tensor& X,
+
23 const torch::Tensor& y)
+
24 {
+
25 validate_tensors(X, y);
+
26
+
27 auto X_cpu = ensure_cpu_tensor(X);
+
28
+
29 n_samples_ = X_cpu.size(0);
+
30 n_features_ = X_cpu.size(1);
+
31
+
32 // Convert tensor data to svm_node structures
+
33 svm_nodes_storage_ = tensor_to_svm_nodes(X_cpu);
+
34
+
35 // Prepare pointers for svm_problem
+
36 svm_x_space_.clear();
+
37 svm_x_space_.reserve(n_samples_);
+
38
+
39 for (auto& nodes : svm_nodes_storage_) {
+
40 svm_x_space_.push_back(nodes.data());
+
41 }
+
42
+
43 // Extract labels if provided
+
44 if (y.defined() && y.numel() > 0) {
+
45 svm_y_space_ = extract_labels(y);
+
46 } else {
+
47 svm_y_space_.clear();
+
48 svm_y_space_.resize(n_samples_, 0.0); // Dummy labels for prediction
+
49 }
+
50
+
51 // Create svm_problem
+
52 auto problem = std::make_unique<svm_problem>();
+
53 problem->l = n_samples_;
+
54 problem->x = svm_x_space_.data();
+
55 problem->y = svm_y_space_.data();
+
56
+
57 return problem;
+
58 }
+
+
59
+
+
60 std::unique_ptr<problem> DataConverter::to_linear_problem(const torch::Tensor& X,
+
61 const torch::Tensor& y)
+
62 {
+
63 validate_tensors(X, y);
+
64
+
65 auto X_cpu = ensure_cpu_tensor(X);
+
66
+
67 n_samples_ = X_cpu.size(0);
+
68 n_features_ = X_cpu.size(1);
+
69
+
70 // Convert tensor data to feature_node structures
+
71 linear_nodes_storage_ = tensor_to_linear_nodes(X_cpu);
+
72
+
73 // Prepare pointers for problem
+
74 linear_x_space_.clear();
+
75 linear_x_space_.reserve(n_samples_);
+
76
+
77 for (auto& nodes : linear_nodes_storage_) {
+
78 linear_x_space_.push_back(nodes.data());
+
79 }
+
80
+
81 // Extract labels if provided
+
82 if (y.defined() && y.numel() > 0) {
+
83 linear_y_space_ = extract_labels(y);
+
84 } else {
+
85 linear_y_space_.clear();
+
86 linear_y_space_.resize(n_samples_, 0.0); // Dummy labels for prediction
+
87 }
+
88
+
89 // Create problem
+
90 auto linear_problem = std::make_unique<problem>();
+
91 linear_problem->l = n_samples_;
+
92 linear_problem->n = n_features_;
+
93 linear_problem->x = linear_x_space_.data();
+
94 linear_problem->y = linear_y_space_.data();
+
95 linear_problem->bias = -1; // No bias term by default
+
96
+
97 return linear_problem;
+
98 }
+
+
99
+
+
100 svm_node* DataConverter::to_svm_node(const torch::Tensor& sample)
+
101 {
+
102 validate_tensor_properties(sample, 1, "sample");
+
103
+
104 auto sample_cpu = ensure_cpu_tensor(sample);
+
105 single_svm_nodes_ = sample_to_svm_nodes(sample_cpu);
+
106
+
107 return single_svm_nodes_.data();
+
108 }
+
+
109
+
+
110 feature_node* DataConverter::to_feature_node(const torch::Tensor& sample)
+
111 {
+
112 validate_tensor_properties(sample, 1, "sample");
+
113
+
114 auto sample_cpu = ensure_cpu_tensor(sample);
+
115 single_linear_nodes_ = sample_to_linear_nodes(sample_cpu);
+
116
+
117 return single_linear_nodes_.data();
+
118 }
+
+
119
+
+
120 torch::Tensor DataConverter::from_predictions(const std::vector<double>& predictions)
+
121 {
+
122 auto options = torch::TensorOptions().dtype(torch::kInt32);
+
123 auto tensor = torch::zeros({ static_cast<int64_t>(predictions.size()) }, options);
+
124
+
125 for (size_t i = 0; i < predictions.size(); ++i) {
+
126 tensor[i] = static_cast<int>(predictions[i]);
+
127 }
+
128
+
129 return tensor;
+
130 }
+
+
131
+
+
132 torch::Tensor DataConverter::from_probabilities(const std::vector<std::vector<double>>& probabilities)
+
133 {
+
134 if (probabilities.empty()) {
+
135 return torch::empty({ 0, 0 });
+
136 }
+
137
+
138 int n_samples = static_cast<int>(probabilities.size());
+
139 int n_classes = static_cast<int>(probabilities[0].size());
+
140
+
141 auto tensor = torch::zeros({ n_samples, n_classes }, torch::kFloat64);
+
142
+
143 for (int i = 0; i < n_samples; ++i) {
+
144 for (int j = 0; j < n_classes; ++j) {
+
145 tensor[i][j] = probabilities[i][j];
+
146 }
+
147 }
+
148
+
149 return tensor;
+
150 }
+
+
151
+
+
152 torch::Tensor DataConverter::from_decision_values(const std::vector<std::vector<double>>& decision_values)
+
153 {
+
154 if (decision_values.empty()) {
+
155 return torch::empty({ 0, 0 });
+
156 }
+
157
+
158 int n_samples = static_cast<int>(decision_values.size());
+
159 int n_values = static_cast<int>(decision_values[0].size());
+
160
+
161 auto tensor = torch::zeros({ n_samples, n_values }, torch::kFloat64);
+
162
+
163 for (int i = 0; i < n_samples; ++i) {
+
164 for (int j = 0; j < n_values; ++j) {
+
165 tensor[i][j] = decision_values[i][j];
+
166 }
+
167 }
+
168
+
169 return tensor;
+
170 }
+
+
171
+
+
172 void DataConverter::validate_tensors(const torch::Tensor& X, const torch::Tensor& y)
+
173 {
+
174 validate_tensor_properties(X, 2, "X");
+
175
+
176 if (y.defined() && y.numel() > 0) {
+
177 validate_tensor_properties(y, 1, "y");
+
178
+
179 // Check that number of samples match
+
180 if (X.size(0) != y.size(0)) {
+
181 throw std::invalid_argument(
+
182 "Number of samples in X (" + std::to_string(X.size(0)) +
+
183 ") does not match number of labels in y (" + std::to_string(y.size(0)) + ")"
+
184 );
+
185 }
+
186 }
+
187
+
188 // Check for reasonable dimensions
+
189 if (X.size(0) == 0) {
+
190 throw std::invalid_argument("X cannot have 0 samples");
+
191 }
+
192
+
193 if (X.size(1) == 0) {
+
194 throw std::invalid_argument("X cannot have 0 features");
+
195 }
+
196 }
+
+
197
+
+ +
199 {
+
200 svm_nodes_storage_.clear();
+
201 svm_x_space_.clear();
+
202 svm_y_space_.clear();
+
203
+
204 linear_nodes_storage_.clear();
+
205 linear_x_space_.clear();
+
206 linear_y_space_.clear();
+
207
+
208 single_svm_nodes_.clear();
+
209 single_linear_nodes_.clear();
+
210
+
211 n_features_ = 0;
+
212 n_samples_ = 0;
+
213 }
+
+
214
+
215 std::vector<std::vector<svm_node>> DataConverter::tensor_to_svm_nodes(const torch::Tensor& X)
+
216 {
+
217 std::vector<std::vector<svm_node>> nodes_storage;
+
218 nodes_storage.reserve(X.size(0));
+
219
+
220 auto X_acc = X.accessor<float, 2>();
+
221
+
222 for (int i = 0; i < X.size(0); ++i) {
+
223 nodes_storage.push_back(sample_to_svm_nodes(X[i]));
+
224 }
+
225
+
226 return nodes_storage;
+
227 }
+
228
+
229 std::vector<std::vector<feature_node>> DataConverter::tensor_to_linear_nodes(const torch::Tensor& X)
+
230 {
+
231 std::vector<std::vector<feature_node>> nodes_storage;
+
232 nodes_storage.reserve(X.size(0));
+
233
+
234 for (int i = 0; i < X.size(0); ++i) {
+
235 nodes_storage.push_back(sample_to_linear_nodes(X[i]));
+
236 }
+
237
+
238 return nodes_storage;
+
239 }
+
240
+
241 std::vector<svm_node> DataConverter::sample_to_svm_nodes(const torch::Tensor& sample)
+
242 {
+
243 std::vector<svm_node> nodes;
+
244
+
245 auto sample_acc = sample.accessor<float, 1>();
+
246
+
247 // Reserve space (worst case: all features are non-sparse)
+
248 nodes.reserve(sample.size(0) + 1); // +1 for terminator
+
249
+
250 for (int j = 0; j < sample.size(0); ++j) {
+
251 double value = static_cast<double>(sample_acc[j]);
+
252
+
253 // Skip sparse features
+
254 if (std::abs(value) > sparse_threshold_) {
+
255 svm_node node;
+
256 node.index = j + 1; // libsvm uses 1-based indexing
+
257 node.value = value;
+
258 nodes.push_back(node);
+
259 }
+
260 }
+
261
+
262 // Add terminator
+
263 svm_node terminator;
+
264 terminator.index = -1;
+
265 terminator.value = 0;
+
266 nodes.push_back(terminator);
+
267
+
268 return nodes;
+
269 }
+
270
+
271 std::vector<feature_node> DataConverter::sample_to_linear_nodes(const torch::Tensor& sample)
+
272 {
+
273 std::vector<feature_node> nodes;
+
274
+
275 auto sample_acc = sample.accessor<float, 1>();
+
276
+
277 // Reserve space (worst case: all features are non-sparse)
+
278 nodes.reserve(sample.size(0) + 1); // +1 for terminator
+
279
+
280 for (int j = 0; j < sample.size(0); ++j) {
+
281 double value = static_cast<double>(sample_acc[j]);
+
282
+
283 // Skip sparse features
+
284 if (std::abs(value) > sparse_threshold_) {
+
285 feature_node node;
+
286 node.index = j + 1; // liblinear uses 1-based indexing
+
287 node.value = value;
+
288 nodes.push_back(node);
+
289 }
+
290 }
+
291
+
292 // Add terminator
+
293 feature_node terminator;
+
294 terminator.index = -1;
+
295 terminator.value = 0;
+
296 nodes.push_back(terminator);
+
297
+
298 return nodes;
+
299 }
+
300
+
301 std::vector<double> DataConverter::extract_labels(const torch::Tensor& y)
+
302 {
+
303 auto y_cpu = ensure_cpu_tensor(y);
+
304 std::vector<double> labels;
+
305 labels.reserve(y_cpu.size(0));
+
306
+
307 // Handle different tensor types
+
308 if (y_cpu.dtype() == torch::kInt32) {
+
309 auto y_acc = y_cpu.accessor<int32_t, 1>();
+
310 for (int i = 0; i < y_cpu.size(0); ++i) {
+
311 labels.push_back(static_cast<double>(y_acc[i]));
+
312 }
+
313 } else if (y_cpu.dtype() == torch::kInt64) {
+
314 auto y_acc = y_cpu.accessor<int64_t, 1>();
+
315 for (int i = 0; i < y_cpu.size(0); ++i) {
+
316 labels.push_back(static_cast<double>(y_acc[i]));
+
317 }
+
318 } else if (y_cpu.dtype() == torch::kFloat32) {
+
319 auto y_acc = y_cpu.accessor<float, 1>();
+
320 for (int i = 0; i < y_cpu.size(0); ++i) {
+
321 labels.push_back(static_cast<double>(y_acc[i]));
+
322 }
+
323 } else if (y_cpu.dtype() == torch::kFloat64) {
+
324 auto y_acc = y_cpu.accessor<double, 1>();
+
325 for (int i = 0; i < y_cpu.size(0); ++i) {
+
326 labels.push_back(y_acc[i]);
+
327 }
+
328 } else {
+
329 throw std::invalid_argument("Unsupported label tensor dtype");
+
330 }
+
331
+
332 return labels;
+
333 }
+
334
+
335 torch::Tensor DataConverter::ensure_cpu_tensor(const torch::Tensor& tensor)
+
336 {
+
337 if (tensor.device().type() != torch::kCPU) {
+
338 return tensor.to(torch::kCPU);
+
339 }
+
340
+
341 // Convert to float32 if not already
+
342 if (tensor.dtype() != torch::kFloat32) {
+
343 return tensor.to(torch::kFloat32);
+
344 }
+
345
+
346 return tensor;
+
347 }
+
348
+
349 void DataConverter::validate_tensor_properties(const torch::Tensor& tensor,
+
350 int expected_dims,
+
351 const std::string& name)
+
352 {
+
353 if (!tensor.defined()) {
+
354 throw std::invalid_argument(name + " tensor is not defined");
+
355 }
+
356
+
357 if (tensor.dim() != expected_dims) {
+
358 throw std::invalid_argument(
+
359 name + " must have " + std::to_string(expected_dims) +
+
360 " dimensions, got " + std::to_string(tensor.dim())
+
361 );
+
362 }
+
363
+
364 if (tensor.numel() == 0) {
+
365 throw std::invalid_argument(name + " tensor cannot be empty");
+
366 }
+
367
+
368 // Check for NaN or Inf values
+
369 if (torch::any(torch::isnan(tensor)).item<bool>()) {
+
370 throw std::invalid_argument(name + " contains NaN values");
+
371 }
+
372
+
373 if (torch::any(torch::isinf(tensor)).item<bool>()) {
+
374 throw std::invalid_argument(name + " contains infinite values");
+
375 }
+
376 }
+
377
+
378} // namespace svm_classifier
+
svm_node * to_svm_node(const torch::Tensor &sample)
Convert single sample to libsvm format.
+
void cleanup()
Clean up all allocated memory.
+
torch::Tensor from_decision_values(const std::vector< std::vector< double > > &decision_values)
Convert decision values back to PyTorch tensor.
+
torch::Tensor from_probabilities(const std::vector< std::vector< double > > &probabilities)
Convert probabilities back to PyTorch tensor.
+
DataConverter()
Default constructor.
+
std::unique_ptr< svm_problem > to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Convert PyTorch tensors to libsvm format.
+
feature_node * to_feature_node(const torch::Tensor &sample)
Convert single sample to liblinear format.
+
std::unique_ptr< problem > to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Convert PyTorch tensors to liblinear format.
+
void validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Validate input tensors.
+
torch::Tensor from_predictions(const std::vector< double > &predictions)
Convert predictions back to PyTorch tensor.
+
~DataConverter()
Destructor - cleans up allocated memory.
+
+ + + + diff --git a/data__converter_8hpp_source.html b/data__converter_8hpp_source.html new file mode 100644 index 0000000..cadfc1c --- /dev/null +++ b/data__converter_8hpp_source.html @@ -0,0 +1,193 @@ + + + + + + + +SVM Classifier C++: include/svm_classifier/data_converter.hpp Source File + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
data_converter.hpp
+
+
+
1#pragma once
+
2
+
3#include "types.hpp"
+
4#include <torch/torch.h>
+
5#include <vector>
+
6#include <memory>
+
7
+
8// Forward declarations for libsvm and liblinear structures
+
9struct svm_node;
+
10struct svm_problem;
+
11struct feature_node;
+
12struct problem;
+
13
+
14namespace svm_classifier {
+
15
+
+ +
24 public:
+ +
29
+ +
34
+
41 std::unique_ptr<svm_problem> to_svm_problem(const torch::Tensor& X,
+
42 const torch::Tensor& y = torch::Tensor());
+
43
+
50 std::unique_ptr<problem> to_linear_problem(const torch::Tensor& X,
+
51 const torch::Tensor& y = torch::Tensor());
+
52
+
58 svm_node* to_svm_node(const torch::Tensor& sample);
+
59
+
65 feature_node* to_feature_node(const torch::Tensor& sample);
+
66
+
72 torch::Tensor from_predictions(const std::vector<double>& predictions);
+
73
+
79 torch::Tensor from_probabilities(const std::vector<std::vector<double>>& probabilities);
+
80
+
86 torch::Tensor from_decision_values(const std::vector<std::vector<double>>& decision_values);
+
87
+
94 void validate_tensors(const torch::Tensor& X, const torch::Tensor& y = torch::Tensor());
+
95
+
100 int get_n_features() const { return n_features_; }
+
101
+
106 int get_n_samples() const { return n_samples_; }
+
107
+
111 void cleanup();
+
112
+
117 void set_sparse_threshold(double threshold) { sparse_threshold_ = threshold; }
+
118
+
123 double get_sparse_threshold() const { return sparse_threshold_; }
+
124
+
125 private:
+
126 int n_features_;
+
127 int n_samples_;
+
128 double sparse_threshold_;
+
129
+
130 // Memory management for libsvm structures
+
131 std::vector<std::vector<svm_node>> svm_nodes_storage_;
+
132 std::vector<svm_node*> svm_x_space_;
+
133 std::vector<double> svm_y_space_;
+
134
+
135 // Memory management for liblinear structures
+
136 std::vector<std::vector<feature_node>> linear_nodes_storage_;
+
137 std::vector<feature_node*> linear_x_space_;
+
138 std::vector<double> linear_y_space_;
+
139
+
140 // Single sample storage (for prediction)
+
141 std::vector<svm_node> single_svm_nodes_;
+
142 std::vector<feature_node> single_linear_nodes_;
+
143
+
149 std::vector<std::vector<svm_node>> tensor_to_svm_nodes(const torch::Tensor& X);
+
150
+
156 std::vector<std::vector<feature_node>> tensor_to_linear_nodes(const torch::Tensor& X);
+
157
+
163 std::vector<svm_node> sample_to_svm_nodes(const torch::Tensor& sample);
+
164
+
170 std::vector<feature_node> sample_to_linear_nodes(const torch::Tensor& sample);
+
171
+
177 std::vector<double> extract_labels(const torch::Tensor& y);
+
178
+
184 torch::Tensor ensure_cpu_tensor(const torch::Tensor& tensor);
+
185
+
192 void validate_tensor_properties(const torch::Tensor& tensor, int expected_dims, const std::string& name);
+
193 };
+
+
194
+
195} // namespace svm_classifier
+
Data converter between libtorch tensors and SVM library formats.
+
int get_n_samples() const
Get number of samples from last conversion.
+
svm_node * to_svm_node(const torch::Tensor &sample)
Convert single sample to libsvm format.
+
double get_sparse_threshold() const
Get sparse threshold.
+
int get_n_features() const
Get number of features from last conversion.
+
void cleanup()
Clean up all allocated memory.
+
torch::Tensor from_decision_values(const std::vector< std::vector< double > > &decision_values)
Convert decision values back to PyTorch tensor.
+
torch::Tensor from_probabilities(const std::vector< std::vector< double > > &probabilities)
Convert probabilities back to PyTorch tensor.
+
DataConverter()
Default constructor.
+
std::unique_ptr< svm_problem > to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Convert PyTorch tensors to libsvm format.
+
feature_node * to_feature_node(const torch::Tensor &sample)
Convert single sample to liblinear format.
+
std::unique_ptr< problem > to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Convert PyTorch tensors to liblinear format.
+
void set_sparse_threshold(double threshold)
Set sparse threshold (features with absolute value below this are ignored)
+
void validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Validate input tensors.
+
torch::Tensor from_predictions(const std::vector< double > &predictions)
Convert predictions back to PyTorch tensor.
+
~DataConverter()
Destructor - cleans up allocated memory.
+
+ + + + diff --git a/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/dir_68267d1309a1af8e8297ef4c3efbcdba.html new file mode 100644 index 0000000..dfd7c8e --- /dev/null +++ b/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -0,0 +1,96 @@ + + + + + + + +SVM Classifier C++: src Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
src Directory Reference
+
+
+ + + + + + + + +

+Files

 data_converter.cpp
 
 kernel_parameters.cpp
 
 multiclass_strategy.cpp
 
+
+ + + + diff --git a/dir_d44c64559bbebec7f509842c48db8b23.html b/dir_d44c64559bbebec7f509842c48db8b23.html new file mode 100644 index 0000000..d9eae14 --- /dev/null +++ b/dir_d44c64559bbebec7f509842c48db8b23.html @@ -0,0 +1,92 @@ + + + + + + + +SVM Classifier C++: include Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
include Directory Reference
+
+
+ + + + +

+Directories

 svm_classifier
 
+
+ + + + diff --git a/dir_daf582bc00f2bbc6516ddb6630e28009.html b/dir_daf582bc00f2bbc6516ddb6630e28009.html new file mode 100644 index 0000000..d8fc8fa --- /dev/null +++ b/dir_daf582bc00f2bbc6516ddb6630e28009.html @@ -0,0 +1,109 @@ + + + + + + + +SVM Classifier C++: include/svm_classifier Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
svm_classifier Directory Reference
+
+
+
+Directory dependency graph for svm_classifier:
+
+
include/svm_classifier
+ + + + +
+ + + + + + + + + + + + +

+Files

 data_converter.hpp
 
 kernel_parameters.hpp
 
 multiclass_strategy.hpp
 
 svm_classifier.hpp
 
 types.hpp
 
+
+ + + + diff --git a/dir_daf582bc00f2bbc6516ddb6630e28009_dep.map b/dir_daf582bc00f2bbc6516ddb6630e28009_dep.map new file mode 100644 index 0000000..c5f0942 --- /dev/null +++ b/dir_daf582bc00f2bbc6516ddb6630e28009_dep.map @@ -0,0 +1,4 @@ + + + + diff --git a/dir_daf582bc00f2bbc6516ddb6630e28009_dep.md5 b/dir_daf582bc00f2bbc6516ddb6630e28009_dep.md5 new file mode 100644 index 0000000..e93d851 --- /dev/null +++ b/dir_daf582bc00f2bbc6516ddb6630e28009_dep.md5 @@ -0,0 +1 @@ +96accfb613001f738468667cac06f43c \ No newline at end of file diff --git a/dir_daf582bc00f2bbc6516ddb6630e28009_dep.png b/dir_daf582bc00f2bbc6516ddb6630e28009_dep.png new file mode 100644 index 0000000..fb9b9c8 Binary files /dev/null and b/dir_daf582bc00f2bbc6516ddb6630e28009_dep.png differ diff --git a/doc.svg b/doc.svg new file mode 100644 index 0000000..0b928a5 --- /dev/null +++ b/doc.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/docd.svg b/docd.svg new file mode 100644 index 0000000..ac18b27 --- /dev/null +++ b/docd.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/doxygen.css b/doxygen.css new file mode 100644 index 0000000..009a9b5 --- /dev/null +++ b/doxygen.css @@ -0,0 +1,2045 @@ +/* The standard CSS for doxygen 1.9.8*/ + +html { +/* page base colors */ +--page-background-color: white; +--page-foreground-color: black; +--page-link-color: #3D578C; +--page-visited-link-color: #4665A2; + +/* index */ +--index-odd-item-bg-color: #F8F9FC; +--index-even-item-bg-color: white; +--index-header-color: black; +--index-separator-color: #A0A0A0; + +/* header */ +--header-background-color: #F9FAFC; +--header-separator-color: #C4CFE5; +--header-gradient-image: url('nav_h.png'); +--group-header-separator-color: #879ECB; +--group-header-color: #354C7B; +--inherit-header-color: gray; + +--footer-foreground-color: #2A3D61; +--footer-logo-width: 104px; +--citation-label-color: #334975; +--glow-color: cyan; + +--title-background-color: white; +--title-separator-color: #5373B4; +--directory-separator-color: #9CAFD4; +--separator-color: #4A6AAA; + +--blockquote-background-color: #F7F8FB; +--blockquote-border-color: #9CAFD4; + +--scrollbar-thumb-color: #9CAFD4; +--scrollbar-background-color: #F9FAFC; + +--icon-background-color: #728DC1; +--icon-foreground-color: white; +--icon-doc-image: url('doc.svg'); +--icon-folder-open-image: url('folderopen.svg'); +--icon-folder-closed-image: url('folderclosed.svg'); + +/* brief member declaration list */ +--memdecl-background-color: #F9FAFC; +--memdecl-separator-color: #DEE4F0; +--memdecl-foreground-color: #555; +--memdecl-template-color: #4665A2; + +/* detailed member list */ +--memdef-border-color: #A8B8D9; +--memdef-title-background-color: #E2E8F2; +--memdef-title-gradient-image: url('nav_f.png'); +--memdef-proto-background-color: #DFE5F1; +--memdef-proto-text-color: #253555; +--memdef-proto-text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--memdef-doc-background-color: white; +--memdef-param-name-color: #602020; +--memdef-template-color: #4665A2; + +/* tables */ +--table-cell-border-color: #2D4068; +--table-header-background-color: #374F7F; +--table-header-foreground-color: #FFFFFF; + +/* labels */ +--label-background-color: #728DC1; +--label-left-top-border-color: #5373B4; +--label-right-bottom-border-color: #C4CFE5; +--label-foreground-color: white; + +/** navigation bar/tree/menu */ +--nav-background-color: #F9FAFC; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_b.png'); +--nav-gradient-hover-image: url('tab_h.png'); +--nav-gradient-active-image: url('tab_a.png'); +--nav-gradient-active-image-parent: url("../tab_a.png"); +--nav-separator-image: url('tab_s.png'); +--nav-breadcrumb-image: url('bc_s.png'); +--nav-breadcrumb-border-color: #C2CDE4; +--nav-splitbar-image: url('splitbar.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #283A5D; +--nav-text-hover-color: white; +--nav-text-active-color: white; +--nav-text-normal-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #364D7C; +--nav-menu-background-color: white; +--nav-menu-foreground-color: #555555; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.5); +--nav-arrow-color: #9CAFD4; +--nav-arrow-selected-color: #9CAFD4; + +/* table of contents */ +--toc-background-color: #F4F6FA; +--toc-border-color: #D8DFEE; +--toc-header-color: #4665A2; +--toc-down-arrow-image: url("data:image/svg+xml;utf8,&%238595;"); + +/** search field */ +--search-background-color: white; +--search-foreground-color: #909090; +--search-magnification-image: url('mag.svg'); +--search-magnification-select-image: url('mag_sel.svg'); +--search-active-color: black; +--search-filter-background-color: #F9FAFC; +--search-filter-foreground-color: black; +--search-filter-border-color: #90A5CE; +--search-filter-highlight-text-color: white; +--search-filter-highlight-bg-color: #3D578C; +--search-results-foreground-color: #425E97; +--search-results-background-color: #EEF1F7; +--search-results-border-color: black; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #555; + +/** code fragments */ +--code-keyword-color: #008000; +--code-type-keyword-color: #604020; +--code-flow-keyword-color: #E08000; +--code-comment-color: #800000; +--code-preprocessor-color: #806020; +--code-string-literal-color: #002080; +--code-char-literal-color: #008080; +--code-xml-cdata-color: black; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #000000; +--code-vhdl-keyword-color: #700070; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #4665A2; +--code-external-link-color: #4665A2; +--fragment-foreground-color: black; +--fragment-background-color: #FBFCFD; +--fragment-border-color: #C4CFE5; +--fragment-lineno-border-color: #00FF00; +--fragment-lineno-background-color: #E8E8E8; +--fragment-lineno-foreground-color: black; +--fragment-lineno-link-fg-color: #4665A2; +--fragment-lineno-link-bg-color: #D8D8D8; +--fragment-lineno-link-hover-fg-color: #4665A2; +--fragment-lineno-link-hover-bg-color: #C8C8C8; +--tooltip-foreground-color: black; +--tooltip-background-color: white; +--tooltip-border-color: gray; +--tooltip-doc-color: grey; +--tooltip-declaration-color: #006318; +--tooltip-link-color: #4665A2; +--tooltip-shadow: 1px 1px 7px gray; +--fold-line-color: #808080; +--fold-minus-image: url('minus.svg'); +--fold-plus-image: url('plus.svg'); +--fold-minus-image-relpath: url('../../minus.svg'); +--fold-plus-image-relpath: url('../../plus.svg'); + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +} + +@media (prefers-color-scheme: dark) { + html:not(.dark-mode) { + color-scheme: dark; + +/* page base colors */ +--page-background-color: black; +--page-foreground-color: #C9D1D9; +--page-link-color: #90A5CE; +--page-visited-link-color: #A3B4D7; + +/* index */ +--index-odd-item-bg-color: #0B101A; +--index-even-item-bg-color: black; +--index-header-color: #C4CFE5; +--index-separator-color: #334975; + +/* header */ +--header-background-color: #070B11; +--header-separator-color: #141C2E; +--header-gradient-image: url('nav_hd.png'); +--group-header-separator-color: #283A5D; +--group-header-color: #90A5CE; +--inherit-header-color: #A0A0A0; + +--footer-foreground-color: #5B7AB7; +--footer-logo-width: 60px; +--citation-label-color: #90A5CE; +--glow-color: cyan; + +--title-background-color: #090D16; +--title-separator-color: #354C79; +--directory-separator-color: #283A5D; +--separator-color: #283A5D; + +--blockquote-background-color: #101826; +--blockquote-border-color: #283A5D; + +--scrollbar-thumb-color: #283A5D; +--scrollbar-background-color: #070B11; + +--icon-background-color: #334975; +--icon-foreground-color: #C4CFE5; +--icon-doc-image: url('docd.svg'); +--icon-folder-open-image: url('folderopend.svg'); +--icon-folder-closed-image: url('folderclosedd.svg'); + +/* brief member declaration list */ +--memdecl-background-color: #0B101A; +--memdecl-separator-color: #2C3F65; +--memdecl-foreground-color: #BBB; +--memdecl-template-color: #7C95C6; + +/* detailed member list */ +--memdef-border-color: #233250; +--memdef-title-background-color: #1B2840; +--memdef-title-gradient-image: url('nav_fd.png'); +--memdef-proto-background-color: #19243A; +--memdef-proto-text-color: #9DB0D4; +--memdef-proto-text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.9); +--memdef-doc-background-color: black; +--memdef-param-name-color: #D28757; +--memdef-template-color: #7C95C6; + +/* tables */ +--table-cell-border-color: #283A5D; +--table-header-background-color: #283A5D; +--table-header-foreground-color: #C4CFE5; + +/* labels */ +--label-background-color: #354C7B; +--label-left-top-border-color: #4665A2; +--label-right-bottom-border-color: #283A5D; +--label-foreground-color: #CCCCCC; + +/** navigation bar/tree/menu */ +--nav-background-color: #101826; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_bd.png'); +--nav-gradient-hover-image: url('tab_hd.png'); +--nav-gradient-active-image: url('tab_ad.png'); +--nav-gradient-active-image-parent: url("../tab_ad.png"); +--nav-separator-image: url('tab_sd.png'); +--nav-breadcrumb-image: url('bc_sd.png'); +--nav-breadcrumb-border-color: #2A3D61; +--nav-splitbar-image: url('splitbard.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #B6C4DF; +--nav-text-hover-color: #DCE2EF; +--nav-text-active-color: #DCE2EF; +--nav-text-normal-shadow: 0px 1px 1px black; +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #B6C4DF; +--nav-menu-background-color: #05070C; +--nav-menu-foreground-color: #BBBBBB; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.2); +--nav-arrow-color: #334975; +--nav-arrow-selected-color: #90A5CE; + +/* table of contents */ +--toc-background-color: #151E30; +--toc-border-color: #202E4A; +--toc-header-color: #A3B4D7; +--toc-down-arrow-image: url("data:image/svg+xml;utf8,&%238595;"); + +/** search field */ +--search-background-color: black; +--search-foreground-color: #C5C5C5; +--search-magnification-image: url('mag_d.svg'); +--search-magnification-select-image: url('mag_seld.svg'); +--search-active-color: #C5C5C5; +--search-filter-background-color: #101826; +--search-filter-foreground-color: #90A5CE; +--search-filter-border-color: #7C95C6; +--search-filter-highlight-text-color: #BCC9E2; +--search-filter-highlight-bg-color: #283A5D; +--search-results-background-color: #101826; +--search-results-foreground-color: #90A5CE; +--search-results-border-color: #7C95C6; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #2F436C; + +/** code fragments */ +--code-keyword-color: #CC99CD; +--code-type-keyword-color: #AB99CD; +--code-flow-keyword-color: #E08000; +--code-comment-color: #717790; +--code-preprocessor-color: #65CABE; +--code-string-literal-color: #7EC699; +--code-char-literal-color: #00E0F0; +--code-xml-cdata-color: #C9D1D9; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #C0C0C0; +--code-vhdl-keyword-color: #CF53C9; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #79C0FF; +--code-external-link-color: #79C0FF; +--fragment-foreground-color: #C9D1D9; +--fragment-background-color: black; +--fragment-border-color: #30363D; +--fragment-lineno-border-color: #30363D; +--fragment-lineno-background-color: black; +--fragment-lineno-foreground-color: #6E7681; +--fragment-lineno-link-fg-color: #6E7681; +--fragment-lineno-link-bg-color: #303030; +--fragment-lineno-link-hover-fg-color: #8E96A1; +--fragment-lineno-link-hover-bg-color: #505050; +--tooltip-foreground-color: #C9D1D9; +--tooltip-background-color: #202020; +--tooltip-border-color: #C9D1D9; +--tooltip-doc-color: #D9E1E9; +--tooltip-declaration-color: #20C348; +--tooltip-link-color: #79C0FF; +--tooltip-shadow: none; +--fold-line-color: #808080; +--fold-minus-image: url('minusd.svg'); +--fold-plus-image: url('plusd.svg'); +--fold-minus-image-relpath: url('../../minusd.svg'); +--fold-plus-image-relpath: url('../../plusd.svg'); + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +}} +body { + background-color: var(--page-background-color); + color: var(--page-foreground-color); +} + +body, table, div, p, dl { + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 22px; +} + +/* @group Heading Levels */ + +.title { + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 28px; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h1.groupheader { + font-size: 150%; +} + +h2.groupheader { + border-bottom: 1px solid var(--group-header-separator-color); + color: var(--group-header-color); + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px var(--glow-color); +} + +dt { + font-weight: bold; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +th p.starttd, th p.intertd, th p.endtd { + font-size: 100%; + font-weight: 700; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.navtab { + padding-right: 15px; + text-align: right; + line-height: 110%; +} + +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL { + background-image: var(--nav-gradient-active-image); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; + width: 100%; + line-height: 140%; + font-size: 130%; + color: var(--index-separator-color); +} + +#main-menu a:focus { + outline: auto; + z-index: 10; + position: relative; +} + +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} + +.alphachar a{ + color: var(--index-header-color); +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; +} + +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.even { + background-color: var(--index-even-item-bg-color); +} + +.classindex dl.odd { + background-color: var(--index-odd-item-bg-color); +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + +/* @group Link Styling */ + +a { + color: var(--page-link-color); + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: var(--page-visited-link-color); +} + +a:hover { + text-decoration: underline; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: var(--code-link-color); +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: var(--code-external-link-color); +} + +a.code.hl_class { /* style for links to class names in code snippets */ } +a.code.hl_struct { /* style for links to struct names in code snippets */ } +a.code.hl_union { /* style for links to union names in code snippets */ } +a.code.hl_interface { /* style for links to interface names in code snippets */ } +a.code.hl_protocol { /* style for links to protocol names in code snippets */ } +a.code.hl_category { /* style for links to category names in code snippets */ } +a.code.hl_exception { /* style for links to exception names in code snippets */ } +a.code.hl_service { /* style for links to service names in code snippets */ } +a.code.hl_singleton { /* style for links to singleton names in code snippets */ } +a.code.hl_concept { /* style for links to concept names in code snippets */ } +a.code.hl_namespace { /* style for links to namespace names in code snippets */ } +a.code.hl_package { /* style for links to package names in code snippets */ } +a.code.hl_define { /* style for links to macro names in code snippets */ } +a.code.hl_function { /* style for links to function names in code snippets */ } +a.code.hl_variable { /* style for links to variable names in code snippets */ } +a.code.hl_typedef { /* style for links to typedef names in code snippets */ } +a.code.hl_enumvalue { /* style for links to enum value names in code snippets */ } +a.code.hl_enumeration { /* style for links to enumeration names in code snippets */ } +a.code.hl_signal { /* style for links to Qt signal names in code snippets */ } +a.code.hl_slot { /* style for links to Qt slot names in code snippets */ } +a.code.hl_friend { /* style for links to friend names in code snippets */ } +a.code.hl_dcop { /* style for links to KDE3 DCOP names in code snippets */ } +a.code.hl_property { /* style for links to property names in code snippets */ } +a.code.hl_event { /* style for links to event names in code snippets */ } +a.code.hl_sequence { /* style for links to sequence names in code snippets */ } +a.code.hl_dictionary { /* style for links to dictionary names in code snippets */ } + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: visible; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; + list-style-type: none; +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid var(--fragment-border-color); + background-color: var(--fragment-background-color); + color: var(--fragment-foreground-color); + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: var(--font-family-monospace); + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + color: var(--fragment-foreground-color); + background-color: var(--fragment-background-color); + border: 1px solid var(--fragment-border-color); +} + +div.line { + font-family: var(--font-family-monospace); + font-size: 13px; + min-height: 13px; + line-height: 1.2; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: var(--glow-color); + box-shadow: 0 0 10px var(--glow-color); +} + +span.fold { + margin-left: 5px; + margin-right: 1px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + display: inline-block; + width: 12px; + height: 12px; + background-repeat:no-repeat; + background-position:center; +} + +span.lineno { + padding-right: 4px; + margin-right: 9px; + text-align: right; + border-right: 2px solid var(--fragment-lineno-border-color); + color: var(--fragment-lineno-foreground-color); + background-color: var(--fragment-lineno-background-color); + white-space: pre; +} +span.lineno a, span.lineno a:visited { + color: var(--fragment-lineno-link-fg-color); + background-color: var(--fragment-lineno-link-bg-color); +} + +span.lineno a:hover { + color: var(--fragment-lineno-link-hover-fg-color); + background-color: var(--fragment-lineno-link-hover-bg-color); +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + color: var(--page-foreground-color); + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +p.formulaDsp { + text-align: center; +} + +img.dark-mode-visible { + display: none; +} +img.light-mode-visible { + display: none; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; + width: var(--footer-logo-width); +} + +.compoundTemplParams { + color: var(--memdecl-template-color); + font-size: 80%; + line-height: 120%; +} + +/* @group Code Colorization */ + +span.keyword { + color: var(--code-keyword-color); +} + +span.keywordtype { + color: var(--code-type-keyword-color); +} + +span.keywordflow { + color: var(--code-flow-keyword-color); +} + +span.comment { + color: var(--code-comment-color); +} + +span.preprocessor { + color: var(--code-preprocessor-color); +} + +span.stringliteral { + color: var(--code-string-literal-color); +} + +span.charliteral { + color: var(--code-char-literal-color); +} + +span.xmlcdata { + color: var(--code-xml-cdata-color); +} + +span.vhdldigit { + color: var(--code-vhdl-digit-color); +} + +span.vhdlchar { + color: var(--code-vhdl-char-color); +} + +span.vhdlkeyword { + color: var(--code-vhdl-keyword-color); +} + +span.vhdllogic { + color: var(--code-vhdl-logic-color); +} + +blockquote { + background-color: var(--blockquote-background-color); + border-left: 2px solid var(--blockquote-border-color); + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid var(--table-cell-border-color); +} + +th.dirtab { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid var(--separator-color); +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: var(--glow-color); + box-shadow: 0 0 15px var(--glow-color); +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: var(--memdecl-background-color); + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: var(--memdecl-foreground-color); +} + +.memSeparator { + border-bottom: 1px solid var(--memdecl-separator-color); + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight, .memTemplItemRight { + width: 100%; +} + +.memTemplParams { + color: var(--memdecl-template-color); + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: var(--memdef-title-gradient-image); + background-repeat: repeat-x; + background-color: var(--memdef-title-background-color); + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: var(--memdef-template-color); + font-weight: normal; + margin-left: 9px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px var(--glow-color); +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + padding: 6px 0px 6px 0px; + color: var(--memdef-proto-text-color); + font-weight: bold; + text-shadow: var(--memdef-proto-text-shadow); + background-color: var(--memdef-proto-background-color); + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; +} + +.overload { + font-family: var(--font-family-monospace); + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + padding: 6px 10px 2px 10px; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: var(--memdef-doc-background-color); + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: var(--memdef-param-name-color); + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: var(--font-family-monospace); + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: var(--label-background-color); + border-top:1px solid var(--label-left-top-border-color); + border-left:1px solid var(--label-left-top-border-color); + border-right:1px solid var(--label-right-bottom-border-color); + border-bottom:1px solid var(--label-right-bottom-border-color); + text-shadow: none; + color: var(--label-foreground-color); + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid var(--directory-separator-color); + border-bottom: 1px solid var(--directory-separator-color); + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.odd { + padding-left: 6px; + background-color: var(--index-odd-item-bg-color); +} + +.directory tr.even { + padding-left: 6px; + background-color: var(--index-even-item-bg-color); +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: var(--page-link-color); +} + +.arrow { + color: var(--nav-arrow-color); + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: var(--font-family-icon); + line-height: normal; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: var(--icon-background-color); + color: var(--icon-foreground-color); + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:var(--icon-folder-open-image); + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:var(--icon-folder-closed-image); + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:var(--icon-doc-image); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: var(--footer-foreground-color); +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid var(--table-cell-border-color); + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + margin-bottom: 10px; + border: 1px solid var(--memdef-border-color); + border-spacing: 0px; + border-radius: 4px; + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid var(--memdef-border-color); + border-bottom: 1px solid var(--memdef-border-color); + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid var(--memdef-border-color); +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image: var(--memdef-title-gradient-image); + background-repeat:repeat-x; + background-color: var(--memdef-title-background-color); + font-size: 90%; + color: var(--memdef-proto-text-color); + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid var(--memdef-border-color); +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: var(--nav-gradient-image); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image: var(--nav-gradient-image); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:var(--nav-text-normal-color); + border:solid 1px var(--nav-breadcrumb-border-color); + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:var(--nav-breadcrumb-image); + background-repeat:no-repeat; + background-position:right; + color: var(--nav-foreground-color); +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: var(--nav-text-normal-color); + font-family: var(--font-family-nav); + text-shadow: var(--nav-text-normal-shadow); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color: var(--footer-foreground-color); + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image: var(--header-gradient-image); + background-repeat:repeat-x; + background-color: var(--header-background-color); + margin: 0px; + border-bottom: 1px solid var(--header-separator-color); +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectrow +{ + height: 56px; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; + padding-left: 0.5em; +} + +#projectname +{ + font-size: 200%; + font-family: var(--font-family-title); + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font-size: 90%; + font-family: var(--font-family-title); + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font-size: 50%; + font-family: 50% var(--font-family-title); + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid var(--title-separator-color); + background-color: var(--title-background-color); +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:var(--citation-label-color); + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; + text-align:right; + width:52px; +} + +dl.citelist dd { + margin:2px 0 2px 72px; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: var(--toc-background-color); + border: 1px solid var(--toc-border-color); + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: var(--toc-down-arrow-image) no-repeat scroll 0 5px transparent; + font: 10px/1.2 var(--font-family-toc); + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 var(--font-family-toc); + color: var(--toc-header-color); + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 15px; +} + +div.toc li.level4 { + margin-left: 15px; +} + +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + +span.obfuscator { + display: none; +} + +.inherit_header { + font-weight: bold; + color: var(--inherit-header-color); + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + /*white-space: nowrap;*/ + color: var(--tooltip-foreground-color); + background-color: var(--tooltip-background-color); + border: 1px solid var(--tooltip-border-color); + border-radius: 4px 4px 4px 4px; + box-shadow: var(--tooltip-shadow); + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: var(--tooltip-doc-color); + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip a { + color: var(--tooltip-link-color); +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: var(--tooltip-declaration-color); +} + +#powerTip div { + margin: 0px; + padding: 0px; + font-size: 12px; + font-family: var(--font-family-tooltip); + line-height: 16px; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: var(--tooltip-background-color); + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before, #powerTip.ne:before, #powerTip.nw:before { + border-top-color: var(--tooltip-border-color); + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: var(--tooltip-background-color); + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: var(--tooltip-border-color); + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: var(--tooltip-border-color); + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: var(--tooltip-border-color); + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: var(--tooltip-border-color); + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: var(--tooltip-border-color); + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid var(--table-cell-border-color); + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +tt, code, kbd, samp +{ + display: inline-block; +} +/* @end */ + +u { + text-decoration: underline; +} + +details>summary { + list-style-type: none; +} + +details > summary::-webkit-details-marker { + display: none; +} + +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; +} + +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; +} + +body { + scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-background-color); +} + +::-webkit-scrollbar { + background-color: var(--scrollbar-background-color); + height: 12px; + width: 12px; +} +::-webkit-scrollbar-thumb { + border-radius: 6px; + box-shadow: inset 0 0 12px 12px var(--scrollbar-thumb-color); + border: solid 2px transparent; +} +::-webkit-scrollbar-corner { + background-color: var(--scrollbar-background-color); +} + diff --git a/doxygen.svg b/doxygen.svg new file mode 100644 index 0000000..79a7635 --- /dev/null +++ b/doxygen.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dynsections.js b/dynsections.js new file mode 100644 index 0000000..9b28156 --- /dev/null +++ b/dynsections.js @@ -0,0 +1,199 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l'); + // add vertical lines to other rows + $('span[class=lineno]').not(':eq(0)').append(''); + // add toggle controls to lines with fold divs + $('div[class=foldopen]').each(function() { + // extract specific id to use + var id = $(this).attr('id').replace('foldopen',''); + // extract start and end foldable fragment attributes + var start = $(this).attr('data-start'); + var end = $(this).attr('data-end'); + // replace normal fold span with controls for the first line of a foldable fragment + $(this).find('span[class=fold]:first').replaceWith(''); + // append div for folded (closed) representation + $(this).after(''); + // extract the first line from the "open" section to represent closed content + var line = $(this).children().first().clone(); + // remove any glow that might still be active on the original line + $(line).removeClass('glow'); + if (start) { + // if line already ends with a start marker (e.g. trailing {), remove it + $(line).html($(line).html().replace(new RegExp('\\s*'+start+'\\s*$','g'),'')); + } + // replace minus with plus symbol + $(line).find('span[class=fold]').css('background-image',plusImg[relPath]); + // append ellipsis + $(line).append(' '+start+''+end); + // insert constructed line into closed div + $('#foldclosed'+id).html(line); + }); +} + +/* @license-end */ +$(document).ready(function() { + $('.code,.codeRef').each(function() { + $(this).data('powertip',$('#a'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); + $.fn.powerTip.smartPlacementLists.s = [ 's', 'n', 'ne', 'se' ]; + $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true }); + }); +}); diff --git a/files.html b/files.html new file mode 100644 index 0000000..b8f3369 --- /dev/null +++ b/files.html @@ -0,0 +1,97 @@ + + + + + + + +SVM Classifier C++: File List + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 123]
+ + + + + + + + + + + +
  include
  svm_classifier
 data_converter.hpp
 kernel_parameters.hpp
 multiclass_strategy.hpp
 svm_classifier.hpp
 types.hpp
  src
 data_converter.cpp
 kernel_parameters.cpp
 multiclass_strategy.cpp
+
+
+ + + + diff --git a/folderclosed.svg b/folderclosed.svg new file mode 100644 index 0000000..b04bed2 --- /dev/null +++ b/folderclosed.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/folderclosedd.svg b/folderclosedd.svg new file mode 100644 index 0000000..52f0166 --- /dev/null +++ b/folderclosedd.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/folderopen.svg b/folderopen.svg new file mode 100644 index 0000000..f6896dd --- /dev/null +++ b/folderopen.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/folderopend.svg b/folderopend.svg new file mode 100644 index 0000000..2d1f06e --- /dev/null +++ b/folderopend.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/functions.html b/functions.html new file mode 100644 index 0000000..3ddc278 --- /dev/null +++ b/functions.html @@ -0,0 +1,204 @@ + + + + + + + +SVM Classifier C++: Class Members + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- v -

+ + +

- ~ -

+
+ + + + diff --git a/functions_func.html b/functions_func.html new file mode 100644 index 0000000..b7c43c1 --- /dev/null +++ b/functions_func.html @@ -0,0 +1,181 @@ + + + + + + + +SVM Classifier C++: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented functions with links to the class documentation for each member:
+ +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- l -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- v -

+ + +

- ~ -

+
+ + + + diff --git a/functions_vars.html b/functions_vars.html new file mode 100644 index 0000000..a012724 --- /dev/null +++ b/functions_vars.html @@ -0,0 +1,96 @@ + + + + + + + +SVM Classifier C++: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented variables with links to the class documentation for each member:
+
+ + + + diff --git a/graph_legend.html b/graph_legend.html new file mode 100644 index 0000000..ed92c31 --- /dev/null +++ b/graph_legend.html @@ -0,0 +1,142 @@ + + + + + + + +SVM Classifier C++: Graph Legend + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Graph Legend
+
+
+

This page explains how to interpret the graphs that are generated by doxygen.

+

Consider the following example:

/*! Invisible class because of truncation */
+
class Invisible { };
+
+
/*! Truncated class, inheritance relation is hidden */
+
class Truncated : public Invisible { };
+
+
/* Class not documented with doxygen comments */
+
class Undocumented { };
+
+
/*! Class that is inherited using public inheritance */
+
class PublicBase : public Truncated { };
+
+
/*! A template class */
+
template<class T> class Templ { };
+
+
/*! Class that is inherited using protected inheritance */
+
class ProtectedBase { };
+
+
/*! Class that is inherited using private inheritance */
+
class PrivateBase { };
+
+
/*! Class that is used by the Inherited class */
+
class Used { };
+
+
/*! Super class that inherits a number of other classes */
+
class Inherited : public PublicBase,
+
protected ProtectedBase,
+
private PrivateBase,
+
public Undocumented,
+
public Templ<int>
+
{
+
private:
+
Used *m_usedClass;
+
};
+

This will result in the following graph:

+

The boxes in the above graph have the following meaning:

+
    +
  • +A filled gray box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a gray border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+

The arrows have the following meaning:

+
    +
  • +A blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labelled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labelled with the template parameters of the instance.
  • +
+
+ + + + diff --git a/graph_legend.md5 b/graph_legend.md5 new file mode 100644 index 0000000..da515da --- /dev/null +++ b/graph_legend.md5 @@ -0,0 +1 @@ +f74606a252eb303675caf37987d0b7af \ No newline at end of file diff --git a/graph_legend.png b/graph_legend.png new file mode 100644 index 0000000..15bf62a Binary files /dev/null and b/graph_legend.png differ diff --git a/hierarchy.html b/hierarchy.html new file mode 100644 index 0000000..abceb2b --- /dev/null +++ b/hierarchy.html @@ -0,0 +1,96 @@ + + + + + + + +SVM Classifier C++: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class Hierarchy
+
+
+
+

Go to the graphical class hierarchy

+This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 12]
+ + + + + + + + +
 Csvm_classifier::DataConverterData converter between libtorch tensors and SVM library formats
 Csvm_classifier::EvaluationMetricsModel evaluation metrics
 Csvm_classifier::MulticlassStrategyBaseAbstract base class for multiclass classification strategies
 Csvm_classifier::OneVsOneStrategyOne-vs-One (OvO) multiclass strategy
 Csvm_classifier::OneVsRestStrategyOne-vs-Rest (OvR) multiclass strategy
 Csvm_classifier::PredictionResultPrediction result structure
 Csvm_classifier::SVMClassifierSupport Vector Machine Classifier with scikit-learn compatible API
 Csvm_classifier::TrainingMetricsTraining metrics structure
+
+
+ + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..2d40763 --- /dev/null +++ b/index.html @@ -0,0 +1,324 @@ + + + + + + + +SVM Classifier C++: SVM Classifier C++ + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
SVM Classifier C++
+
+
+

A high-performance Support Vector Machine classifier implementation in C++ with a scikit-learn compatible API. This library provides a unified interface for SVM classification using both liblinear (for linear kernels) and libsvm (for non-linear kernels), with support for multiclass classification and PyTorch tensor integration.

+

Features

+
    +
  • 🚀 Scikit-learn Compatible API: Familiar fit(), predict(), predict_proba(), score() methods
  • +
  • 🔧 Multiple Kernels: Linear, RBF, Polynomial, and Sigmoid kernels
  • +
  • 📊 Multiclass Support: One-vs-Rest (OvR) and One-vs-One (OvO) strategies
  • +
  • ⚡ Automatic Library Selection: Uses liblinear for linear kernels, libsvm for others
  • +
  • 🔗 PyTorch Integration: Native support for libtorch tensors
  • +
  • ⚙️ JSON Configuration: Easy parameter management with nlohmann::json
  • +
  • 🧪 Comprehensive Testing: 100% test coverage with Catch2
  • +
  • 📈 Performance Metrics: Detailed evaluation and training metrics
  • +
  • 🔍 Cross-Validation: Built-in k-fold cross-validation support
  • +
  • 🎯 Grid Search: Hyperparameter optimization capabilities
  • +
+

Quick Start

+

Prerequisites

+
    +
  • C++17 or later
  • +
  • CMake 3.15+
  • +
  • libtorch
  • +
  • Git
  • +
+

Building

+
git clone <repository-url>
+
cd svm_classifier
+
mkdir build && cd build
+
cmake ..
+
make -j$(nproc)
+

Basic Usage

+
#include <svm_classifier/svm_classifier.hpp>
+
#include <torch/torch.h>
+
+
using namespace svm_classifier;
+
+
// Create sample data
+
auto X = torch::randn({100, 2}); // 100 samples, 2 features
+
auto y = torch::randint(0, 3, {100}); // 3 classes
+
+
// Create and train SVM
+
SVMClassifier svm(KernelType::RBF, 1.0);
+
auto metrics = svm.fit(X, y);
+
+
// Make predictions
+
auto predictions = svm.predict(X);
+
auto probabilities = svm.predict_proba(X);
+
double accuracy = svm.score(X, y);
+
Support Vector Machine Classifier with scikit-learn compatible API.
+

JSON Configuration

+
#include <nlohmann/json.hpp>
+
+
nlohmann::json config = {
+
{"kernel", "rbf"},
+
{"C", 10.0},
+
{"gamma", 0.1},
+
{"multiclass_strategy", "ovo"},
+
{"probability", true}
+
};
+
+
SVMClassifier svm(config);
+

API Reference

+

Constructor Options

+
// Default constructor
+ +
+
// With explicit parameters
+
SVMClassifier svm(KernelType::RBF, 1.0, MulticlassStrategy::ONE_VS_REST);
+
+
// From JSON configuration
+
SVMClassifier svm(config_json);
+

Core Methods

+ + + + + + + + + + + + + + + + + +
Method Description Returns
fit(X, y) Train the classifier TrainingMetrics
predict(X) Predict class labels torch::Tensor
predict_proba(X) Predict class probabilities torch::Tensor
score(X, y) Calculate accuracy double
decision_function(X) Get decision values torch::Tensor
cross_validate(X, y, cv) K-fold cross-validation std::vector<double>
grid_search(X, y, grid, cv) Hyperparameter tuning nlohmann::json
+

Parameter Configuration

+

Common Parameters

+
    +
  • kernel: "linear", "rbf", "polynomial", "sigmoid"
  • +
  • C: Regularization parameter (default: 1.0)
  • +
  • multiclass_strategy: "ovr" (One-vs-Rest) or "ovo" (One-vs-One)
  • +
  • probability: Enable probability estimates (default: false)
  • +
  • tolerance: Convergence tolerance (default: 1e-3)
  • +
+

Kernel-Specific Parameters

+
    +
  • RBF/Polynomial/Sigmoid: gamma (default: auto)
  • +
  • Polynomial: degree (default: 3), coef0 (default: 0.0)
  • +
  • Sigmoid: coef0 (default: 0.0)
  • +
+

Examples

+

Multi-class Classification

+
// Generate multi-class dataset
+
auto X = torch::randn({300, 4});
+
auto y = torch::randint(0, 5, {300}); // 5 classes
+
+
// Configure for multi-class
+
nlohmann::json config = {
+
{"kernel", "rbf"},
+
{"C", 1.0},
+
{"gamma", 0.1},
+
{"multiclass_strategy", "ovo"},
+
{"probability", true}
+
};
+
+
SVMClassifier svm(config);
+
auto metrics = svm.fit(X, y);
+
+
// Evaluate
+
auto eval_metrics = svm.evaluate(X, y);
+
std::cout << "Accuracy: " << eval_metrics.accuracy << std::endl;
+
std::cout << "F1-Score: " << eval_metrics.f1_score << std::endl;
+
EvaluationMetrics evaluate(const torch::Tensor &X, const torch::Tensor &y_true)
Calculate detailed evaluation metrics.
+
TrainingMetrics fit(const torch::Tensor &X, const torch::Tensor &y)
Train the SVM classifier.
+
double accuracy
Classification accuracy.
Definition types.hpp:71
+

Cross-Validation

+
SVMClassifier svm(KernelType::RBF);
+
auto cv_scores = svm.cross_validate(X, y, 5); // 5-fold CV
+
+
double mean_score = 0.0;
+
for (auto score : cv_scores) {
+
mean_score += score;
+
}
+
mean_score /= cv_scores.size();
+
std::vector< double > cross_validate(const torch::Tensor &X, const torch::Tensor &y, int cv=5)
Perform cross-validation.
+

Grid Search

+
nlohmann::json param_grid = {
+
{"C", {0.1, 1.0, 10.0}},
+
{"gamma", {0.01, 0.1, 1.0}},
+
{"kernel", {"rbf", "polynomial"}}
+
};
+
+
auto best_params = svm.grid_search(X, y, param_grid, 3);
+
std::cout << "Best parameters: " << best_params.dump(2) << std::endl;
+
nlohmann::json grid_search(const torch::Tensor &X, const torch::Tensor &y, const nlohmann::json &param_grid, int cv=5)
Find optimal hyperparameters using grid search.
+

Testing

+

Run All Tests

+
cd build
+
make test_all
+

Test Categories

+
make test_unit # Unit tests
+
make test_integration # Integration tests
+
make test_performance # Performance tests
+

Coverage Report

+
cmake -DCMAKE_BUILD_TYPE=Debug ..
+
make coverage
+

The coverage report will be generated in build/coverage_html/index.html.

+

Project Structure

+
svm_classifier/
+
├── include/svm_classifier/ # Public headers
+
│ ├── svm_classifier.hpp # Main classifier interface
+
│ ├── data_converter.hpp # Tensor conversion utilities
+
│ ├── multiclass_strategy.hpp # Multiclass strategies
+
│ ├── kernel_parameters.hpp # Parameter management
+
│ └── types.hpp # Common types and enums
+
├── src/ # Implementation files
+
├── tests/ # Comprehensive test suite
+
├── examples/ # Usage examples
+
├── external/ # Third-party dependencies
+
└── CMakeLists.txt # Build configuration
+

Dependencies

+

Required

+
    +
  • libtorch: PyTorch C++ API for tensor operations
  • +
  • liblinear: Linear SVM implementation
  • +
  • libsvm: Non-linear SVM implementation
  • +
  • nlohmann/json: JSON configuration handling
  • +
+

Testing

+
    +
  • Catch2: Testing framework
  • +
+

Build System

+
    +
  • CMake: Cross-platform build system
  • +
+

Performance Characteristics

+

Memory Usage

+
    +
  • Efficient sparse data handling
  • +
  • Automatic memory management for SVM structures
  • +
  • Configurable cache sizes for large datasets
  • +
+

Speed

+
    +
  • Linear kernels: Uses highly optimized liblinear
  • +
  • Non-linear kernels: Uses proven libsvm implementation
  • +
  • Multi-threading support via libtorch
  • +
+

Scalability

+
    +
  • Handles datasets from hundreds to millions of samples
  • +
  • Memory-efficient data conversion
  • +
  • Sparse feature support
  • +
+

Library Selection Logic

+

The classifier automatically selects the appropriate underlying library:

+
    +
  • Linear Kernel → liblinear (optimized for linear classification)
  • +
  • RBF/Polynomial/Sigmoid → libsvm (supports arbitrary kernels)
  • +
+

This ensures optimal performance for each kernel type while maintaining a unified API.

+

Contributing

+
    +
  1. Fork the repository
  2. +
  3. Create a feature branch
  4. +
  5. Add tests for new functionality
  6. +
  7. Ensure all tests pass: make test_all
  8. +
  9. Check code coverage: make coverage
  10. +
  11. Submit a pull request
  12. +
+

Code Style

+
    +
  • Follow modern C++17 conventions
  • +
  • Use RAII for resource management
  • +
  • Comprehensive error handling
  • +
  • Document all public APIs
  • +
+

License

+

[Specify your license here]

+

Acknowledgments

+
    +
  • libsvm: Chih-Chung Chang and Chih-Jen Lin
  • +
  • liblinear: Fan et al.
  • +
  • PyTorch: Facebook AI Research
  • +
  • nlohmann/json: Niels Lohmann
  • +
  • Catch2: Phil Nash and contributors
  • +
+
+
+ + + + diff --git a/inherit_graph_0.map b/inherit_graph_0.map new file mode 100644 index 0000000..b135c20 --- /dev/null +++ b/inherit_graph_0.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_0.md5 b/inherit_graph_0.md5 new file mode 100644 index 0000000..1062f0f --- /dev/null +++ b/inherit_graph_0.md5 @@ -0,0 +1 @@ +2e8df4a058152ec339b955b6756e2b14 \ No newline at end of file diff --git a/inherit_graph_0.png b/inherit_graph_0.png new file mode 100644 index 0000000..952acfa Binary files /dev/null and b/inherit_graph_0.png differ diff --git a/inherit_graph_1.map b/inherit_graph_1.map new file mode 100644 index 0000000..a88b60a --- /dev/null +++ b/inherit_graph_1.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_1.md5 b/inherit_graph_1.md5 new file mode 100644 index 0000000..a0a6dbc --- /dev/null +++ b/inherit_graph_1.md5 @@ -0,0 +1 @@ +5f78d14619959ec8ed1a58be62b4611e \ No newline at end of file diff --git a/inherit_graph_1.png b/inherit_graph_1.png new file mode 100644 index 0000000..b349fde Binary files /dev/null and b/inherit_graph_1.png differ diff --git a/inherit_graph_2.map b/inherit_graph_2.map new file mode 100644 index 0000000..3b7afd4 --- /dev/null +++ b/inherit_graph_2.map @@ -0,0 +1,7 @@ + + + + + + + diff --git a/inherit_graph_2.md5 b/inherit_graph_2.md5 new file mode 100644 index 0000000..72d7af0 --- /dev/null +++ b/inherit_graph_2.md5 @@ -0,0 +1 @@ +8a7b17b3fadc2ef6f3911678ccf5b08d \ No newline at end of file diff --git a/inherit_graph_2.png b/inherit_graph_2.png new file mode 100644 index 0000000..4c80498 Binary files /dev/null and b/inherit_graph_2.png differ diff --git a/inherit_graph_3.map b/inherit_graph_3.map new file mode 100644 index 0000000..2f1f5b3 --- /dev/null +++ b/inherit_graph_3.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_3.md5 b/inherit_graph_3.md5 new file mode 100644 index 0000000..1fc55a7 --- /dev/null +++ b/inherit_graph_3.md5 @@ -0,0 +1 @@ +bb7e66c7bf0f7d1f1b765560fe9d8d09 \ No newline at end of file diff --git a/inherit_graph_3.png b/inherit_graph_3.png new file mode 100644 index 0000000..149e9f1 Binary files /dev/null and b/inherit_graph_3.png differ diff --git a/inherit_graph_4.map b/inherit_graph_4.map new file mode 100644 index 0000000..1c009b3 --- /dev/null +++ b/inherit_graph_4.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_4.md5 b/inherit_graph_4.md5 new file mode 100644 index 0000000..1916a82 --- /dev/null +++ b/inherit_graph_4.md5 @@ -0,0 +1 @@ +666715255347d0578141c5a73142eaf0 \ No newline at end of file diff --git a/inherit_graph_4.png b/inherit_graph_4.png new file mode 100644 index 0000000..d947b47 Binary files /dev/null and b/inherit_graph_4.png differ diff --git a/inherit_graph_5.map b/inherit_graph_5.map new file mode 100644 index 0000000..0eb342d --- /dev/null +++ b/inherit_graph_5.map @@ -0,0 +1,3 @@ + + + diff --git a/inherit_graph_5.md5 b/inherit_graph_5.md5 new file mode 100644 index 0000000..83c3638 --- /dev/null +++ b/inherit_graph_5.md5 @@ -0,0 +1 @@ +5cfab252f5cdcaa54e79ae7b0e323201 \ No newline at end of file diff --git a/inherit_graph_5.png b/inherit_graph_5.png new file mode 100644 index 0000000..d21329c Binary files /dev/null and b/inherit_graph_5.png differ diff --git a/inherits.html b/inherits.html new file mode 100644 index 0000000..f70c859 --- /dev/null +++ b/inherits.html @@ -0,0 +1,120 @@ + + + + + + + +SVM Classifier C++: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class Hierarchy
+
+
+ + + + + + + +
+ + + +
+ + + +
+ + + + + + + +
+ + + +
+ + + +
+ + + +
+
+ + + + diff --git a/jquery.js b/jquery.js new file mode 100644 index 0000000..1dffb65 --- /dev/null +++ b/jquery.js @@ -0,0 +1,34 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/kernel__parameters_8cpp_source.html b/kernel__parameters_8cpp_source.html new file mode 100644 index 0000000..d789f55 --- /dev/null +++ b/kernel__parameters_8cpp_source.html @@ -0,0 +1,439 @@ + + + + + + + +SVM Classifier C++: src/kernel_parameters.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
kernel_parameters.cpp
+
+
+
1#include "svm_classifier/kernel_parameters.hpp"
+
2#include <stdexcept>
+
3#include <cmath>
+
4
+
5namespace svm_classifier {
+
6
+
7 KernelParameters::KernelParameters()
+
8 : kernel_type_(KernelType::LINEAR)
+
9 , multiclass_strategy_(MulticlassStrategy::ONE_VS_REST)
+
10 , C_(1.0)
+
11 , tolerance_(1e-3)
+
12 , max_iterations_(-1)
+
13 , probability_(false)
+
14 , gamma_(-1.0) // Auto gamma
+
15 , degree_(3)
+
16 , coef0_(0.0)
+
17 , cache_size_(200.0)
+
18 {
+
19 }
+
20
+
21 KernelParameters::KernelParameters(const nlohmann::json& config) : KernelParameters()
+
22 {
+
23 set_parameters(config);
+
24 }
+
25
+
26 void KernelParameters::set_parameters(const nlohmann::json& config)
+
27 {
+
28 // Set kernel type first as it affects validation
+
29 if (config.contains("kernel")) {
+
30 if (config["kernel"].is_string()) {
+
31 set_kernel_type(string_to_kernel_type(config["kernel"]));
+
32 } else {
+
33 throw std::invalid_argument("Kernel must be a string");
+
34 }
+
35 }
+
36
+
37 // Set multiclass strategy
+
38 if (config.contains("multiclass_strategy")) {
+
39 if (config["multiclass_strategy"].is_string()) {
+
40 set_multiclass_strategy(string_to_multiclass_strategy(config["multiclass_strategy"]));
+
41 } else {
+
42 throw std::invalid_argument("Multiclass strategy must be a string");
+
43 }
+
44 }
+
45
+
46 // Set common parameters
+
47 if (config.contains("C")) {
+
48 if (config["C"].is_number()) {
+
49 set_C(config["C"]);
+
50 } else {
+
51 throw std::invalid_argument("C must be a number");
+
52 }
+
53 }
+
54
+
55 if (config.contains("tolerance")) {
+
56 if (config["tolerance"].is_number()) {
+
57 set_tolerance(config["tolerance"]);
+
58 } else {
+
59 throw std::invalid_argument("Tolerance must be a number");
+
60 }
+
61 }
+
62
+
63 if (config.contains("max_iterations")) {
+
64 if (config["max_iterations"].is_number_integer()) {
+
65 set_max_iterations(config["max_iterations"]);
+
66 } else {
+
67 throw std::invalid_argument("Max iterations must be an integer");
+
68 }
+
69 }
+
70
+
71 if (config.contains("probability")) {
+
72 if (config["probability"].is_boolean()) {
+
73 set_probability(config["probability"]);
+
74 } else {
+
75 throw std::invalid_argument("Probability must be a boolean");
+
76 }
+
77 }
+
78
+
79 // Set kernel-specific parameters
+
80 if (config.contains("gamma")) {
+
81 if (config["gamma"].is_number()) {
+
82 set_gamma(config["gamma"]);
+
83 } else if (config["gamma"].is_string() && config["gamma"] == "auto") {
+
84 set_gamma(-1.0); // Auto gamma
+
85 } else {
+
86 throw std::invalid_argument("Gamma must be a number or 'auto'");
+
87 }
+
88 }
+
89
+
90 if (config.contains("degree")) {
+
91 if (config["degree"].is_number_integer()) {
+
92 set_degree(config["degree"]);
+
93 } else {
+
94 throw std::invalid_argument("Degree must be an integer");
+
95 }
+
96 }
+
97
+
98 if (config.contains("coef0")) {
+
99 if (config["coef0"].is_number()) {
+
100 set_coef0(config["coef0"]);
+
101 } else {
+
102 throw std::invalid_argument("Coef0 must be a number");
+
103 }
+
104 }
+
105
+
106 if (config.contains("cache_size")) {
+
107 if (config["cache_size"].is_number()) {
+
108 set_cache_size(config["cache_size"]);
+
109 } else {
+
110 throw std::invalid_argument("Cache size must be a number");
+
111 }
+
112 }
+
113
+
114 // Validate all parameters
+
115 validate();
+
116 }
+
117
+
118 nlohmann::json KernelParameters::get_parameters() const
+
119 {
+
120 nlohmann::json params = {
+
121 {"kernel", kernel_type_to_string(kernel_type_)},
+
122 {"multiclass_strategy", multiclass_strategy_to_string(multiclass_strategy_)},
+
123 {"C", C_},
+
124 {"tolerance", tolerance_},
+
125 {"max_iterations", max_iterations_},
+
126 {"probability", probability_},
+
127 {"cache_size", cache_size_}
+
128 };
+
129
+
130 // Add kernel-specific parameters
+
131 switch (kernel_type_) {
+
132 case KernelType::LINEAR:
+
133 // No additional parameters for linear kernel
+
134 break;
+
135
+
136 case KernelType::RBF:
+
137 params["gamma"] = is_gamma_auto() ? "auto" : gamma_;
+
138 break;
+
139
+
140 case KernelType::POLYNOMIAL:
+
141 params["degree"] = degree_;
+
142 params["gamma"] = is_gamma_auto() ? "auto" : gamma_;
+
143 params["coef0"] = coef0_;
+
144 break;
+
145
+
146 case KernelType::SIGMOID:
+
147 params["gamma"] = is_gamma_auto() ? "auto" : gamma_;
+
148 params["coef0"] = coef0_;
+
149 break;
+
150 }
+
151
+
152 return params;
+
153 }
+
154
+
155 void KernelParameters::set_kernel_type(KernelType kernel)
+
156 {
+
157 kernel_type_ = kernel;
+
158
+
159 // Reset kernel-specific parameters to defaults when kernel changes
+
160 auto defaults = get_default_parameters(kernel);
+
161
+
162 if (defaults.contains("gamma")) {
+
163 gamma_ = defaults["gamma"];
+
164 }
+
165 if (defaults.contains("degree")) {
+
166 degree_ = defaults["degree"];
+
167 }
+
168 if (defaults.contains("coef0")) {
+
169 coef0_ = defaults["coef0"];
+
170 }
+
171 }
+
172
+
173 void KernelParameters::set_C(double c)
+
174 {
+
175 if (c <= 0.0) {
+
176 throw std::invalid_argument("C must be positive (C > 0)");
+
177 }
+
178 C_ = c;
+
179 }
+
180
+
181 void KernelParameters::set_gamma(double gamma)
+
182 {
+
183 // Allow negative values for auto gamma (-1.0)
+
184 if (gamma > 0.0 || gamma == -1.0) {
+
185 gamma_ = gamma;
+
186 } else {
+
187 throw std::invalid_argument("Gamma must be positive or -1 for auto");
+
188 }
+
189 }
+
190
+
191 void KernelParameters::set_degree(int degree)
+
192 {
+
193 if (degree < 1) {
+
194 throw std::invalid_argument("Degree must be >= 1");
+
195 }
+
196 degree_ = degree;
+
197 }
+
198
+
199 void KernelParameters::set_coef0(double coef0)
+
200 {
+
201 coef0_ = coef0;
+
202 }
+
203
+
204 void KernelParameters::set_tolerance(double tol)
+
205 {
+
206 if (tol <= 0.0) {
+
207 throw std::invalid_argument("Tolerance must be positive (tolerance > 0)");
+
208 }
+
209 tolerance_ = tol;
+
210 }
+
211
+
212 void KernelParameters::set_max_iterations(int max_iter)
+
213 {
+
214 if (max_iter <= 0 && max_iter != -1) {
+
215 throw std::invalid_argument("Max iterations must be positive or -1 for no limit");
+
216 }
+
217 max_iterations_ = max_iter;
+
218 }
+
219
+
220 void KernelParameters::set_cache_size(double cache_size)
+
221 {
+
222 if (cache_size < 0.0) {
+
223 throw std::invalid_argument("Cache size must be non-negative");
+
224 }
+
225 cache_size_ = cache_size;
+
226 }
+
227
+
228 void KernelParameters::set_probability(bool probability)
+
229 {
+
230 probability_ = probability;
+
231 }
+
232
+
233 void KernelParameters::set_multiclass_strategy(MulticlassStrategy strategy)
+
234 {
+
235 multiclass_strategy_ = strategy;
+
236 }
+
237
+
238 void KernelParameters::validate() const
+
239 {
+
240 // Validate common parameters
+
241 if (C_ <= 0.0) {
+
242 throw std::invalid_argument("C must be positive");
+
243 }
+
244
+
245 if (tolerance_ <= 0.0) {
+
246 throw std::invalid_argument("Tolerance must be positive");
+
247 }
+
248
+
249 if (max_iterations_ <= 0 && max_iterations_ != -1) {
+
250 throw std::invalid_argument("Max iterations must be positive or -1");
+
251 }
+
252
+
253 if (cache_size_ < 0.0) {
+
254 throw std::invalid_argument("Cache size must be non-negative");
+
255 }
+
256
+
257 // Validate kernel-specific parameters
+
258 validate_kernel_parameters();
+
259 }
+
260
+
261 void KernelParameters::validate_kernel_parameters() const
+
262 {
+
263 switch (kernel_type_) {
+
264 case KernelType::LINEAR:
+
265 // Linear kernel has no additional parameters to validate
+
266 break;
+
267
+
268 case KernelType::RBF:
+
269 if (gamma_ > 0.0 || gamma_ == -1.0) {
+
270 // Valid gamma (positive or auto)
+
271 } else {
+
272 throw std::invalid_argument("RBF kernel gamma must be positive or auto (-1)");
+
273 }
+
274 break;
+
275
+
276 case KernelType::POLYNOMIAL:
+
277 if (degree_ < 1) {
+
278 throw std::invalid_argument("Polynomial degree must be >= 1");
+
279 }
+
280 if (gamma_ > 0.0 || gamma_ == -1.0) {
+
281 // Valid gamma
+
282 } else {
+
283 throw std::invalid_argument("Polynomial kernel gamma must be positive or auto (-1)");
+
284 }
+
285 // coef0 can be any real number
+
286 break;
+
287
+
288 case KernelType::SIGMOID:
+
289 if (gamma_ > 0.0 || gamma_ == -1.0) {
+
290 // Valid gamma
+
291 } else {
+
292 throw std::invalid_argument("Sigmoid kernel gamma must be positive or auto (-1)");
+
293 }
+
294 // coef0 can be any real number
+
295 break;
+
296 }
+
297 }
+
298
+
299 nlohmann::json KernelParameters::get_default_parameters(KernelType kernel)
+
300 {
+
301 nlohmann::json defaults = {
+
302 {"C", 1.0},
+
303 {"tolerance", 1e-3},
+
304 {"max_iterations", -1},
+
305 {"probability", false},
+
306 {"multiclass_strategy", "ovr"},
+
307 {"cache_size", 200.0}
+
308 };
+
309
+
310 switch (kernel) {
+
311 case KernelType::LINEAR:
+
312 defaults["kernel"] = "linear";
+
313 break;
+
314
+
315 case KernelType::RBF:
+
316 defaults["kernel"] = "rbf";
+
317 defaults["gamma"] = -1.0; // Auto gamma
+
318 break;
+
319
+
320 case KernelType::POLYNOMIAL:
+
321 defaults["kernel"] = "polynomial";
+
322 defaults["degree"] = 3;
+
323 defaults["gamma"] = -1.0; // Auto gamma
+
324 defaults["coef0"] = 0.0;
+
325 break;
+
326
+
327 case KernelType::SIGMOID:
+
328 defaults["kernel"] = "sigmoid";
+
329 defaults["gamma"] = -1.0; // Auto gamma
+
330 defaults["coef0"] = 0.0;
+
331 break;
+
332 }
+
333
+
334 return defaults;
+
335 }
+
336
+
337 void KernelParameters::reset_to_defaults()
+
338 {
+
339 auto defaults = get_default_parameters(kernel_type_);
+
340 set_parameters(defaults);
+
341 }
+
342
+
343 void KernelParameters::set_gamma_auto()
+
344 {
+
345 gamma_ = -1.0;
+
346 }
+
347
+
348} // namespace svm_classifier
+
+ + + + diff --git a/kernel__parameters_8hpp_source.html b/kernel__parameters_8hpp_source.html new file mode 100644 index 0000000..018bdf4 --- /dev/null +++ b/kernel__parameters_8hpp_source.html @@ -0,0 +1,190 @@ + + + + + + + +SVM Classifier C++: include/svm_classifier/kernel_parameters.hpp Source File + + + + + + + + + +
+
+ + + + + + +
+
SVM Classifier C++ 1.0.0 +
+
High-performance Support Vector Machine classifier with scikit-learn compatible API
+
+
+ + + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
kernel_parameters.hpp
+
+
+
1#pragma once
+
2
+
3#include "types.hpp"
+
4#include <torch/torch.h>
+
5#include <vector>
+
6#include <memory>
+
7
+
8// Forward declarations for libsvm and liblinear structures
+
9struct svm_node;
+
10struct svm_problem;
+
11struct feature_node;
+
12struct problem;
+
13
+
14namespace svm_classifier {
+
15
+
23 class DataConverter {
+
24 public:
+ +
29
+ +
34
+
41 std::unique_ptr<svm_problem> to_svm_problem(const torch::Tensor& X,
+
42 const torch::Tensor& y = torch::Tensor());
+
43
+
50 std::unique_ptr<problem> to_linear_problem(const torch::Tensor& X,
+
51 const torch::Tensor& y = torch::Tensor());
+
52
+
58 svm_node* to_svm_node(const torch::Tensor& sample);
+
59
+
65 feature_node* to_feature_node(const torch::Tensor& sample);
+
66
+
72 torch::Tensor from_predictions(const std::vector<double>& predictions);
+
73
+
79 torch::Tensor from_probabilities(const std::vector<std::vector<double>>& probabilities);
+
80
+
86 torch::Tensor from_decision_values(const std::vector<std::vector<double>>& decision_values);
+
87
+
94 void validate_tensors(const torch::Tensor& X, const torch::Tensor& y = torch::Tensor());
+
95
+
100 int get_n_features() const { return n_features_; }
+
101
+
106 int get_n_samples() const { return n_samples_; }
+
107
+
111 void cleanup();
+
112
+
117 void set_sparse_threshold(double threshold) { sparse_threshold_ = threshold; }
+
118
+
123 double get_sparse_threshold() const { return sparse_threshold_; }
+
124
+
125 private:
+
126 int n_features_;
+
127 int n_samples_;
+
128 double sparse_threshold_;
+
129
+
130 // Memory management for libsvm structures
+
131 std::vector<std::vector<svm_node>> svm_nodes_storage_;
+
132 std::vector<svm_node*> svm_x_space_;
+
133 std::vector<double> svm_y_space_;
+
134
+
135 // Memory management for liblinear structures
+
136 std::vector<std::vector<feature_node>> linear_nodes_storage_;
+
137 std::vector<feature_node*> linear_x_space_;
+
138 std::vector<double> linear_y_space_;
+
139
+
140 // Single sample storage (for prediction)
+
141 std::vector<svm_node> single_svm_nodes_;
+
142 std::vector<feature_node> single_linear_nodes_;
+
143
+
149 std::vector<std::vector<svm_node>> tensor_to_svm_nodes(const torch::Tensor& X);
+
150
+
156 std::vector<std::vector<feature_node>> tensor_to_linear_nodes(const torch::Tensor& X);
+
157
+
163 std::vector<svm_node> sample_to_svm_nodes(const torch::Tensor& sample);
+
164
+
170 std::vector<feature_node> sample_to_linear_nodes(const torch::Tensor& sample);
+
171
+
177 std::vector<double> extract_labels(const torch::Tensor& y);
+
178
+
184 torch::Tensor ensure_cpu_tensor(const torch::Tensor& tensor);
+
185
+
192 void validate_tensor_properties(const torch::Tensor& tensor, int expected_dims, const std::string& name);
+
193 };
+
194
+
195} // namespace svm_classifier
+
int get_n_samples() const
Get number of samples from last conversion.
+
svm_node * to_svm_node(const torch::Tensor &sample)
Convert single sample to libsvm format.
+
double get_sparse_threshold() const
Get sparse threshold.
+
int get_n_features() const
Get number of features from last conversion.
+
void cleanup()
Clean up all allocated memory.
+
torch::Tensor from_decision_values(const std::vector< std::vector< double > > &decision_values)
Convert decision values back to PyTorch tensor.
+
torch::Tensor from_probabilities(const std::vector< std::vector< double > > &probabilities)
Convert probabilities back to PyTorch tensor.
+
DataConverter()
Default constructor.
+
std::unique_ptr< svm_problem > to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Convert PyTorch tensors to libsvm format.
+
feature_node * to_feature_node(const torch::Tensor &sample)
Convert single sample to liblinear format.
+
std::unique_ptr< problem > to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Convert PyTorch tensors to liblinear format.
+
void set_sparse_threshold(double threshold)
Set sparse threshold (features with absolute value below this are ignored)
+
void validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())
Validate input tensors.
+
torch::Tensor from_predictions(const std::vector< double > &predictions)
Convert predictions back to PyTorch tensor.
+
~DataConverter()
Destructor - cleans up allocated memory.
+
+ + + + diff --git a/menu.js b/menu.js new file mode 100644 index 0000000..b0b2693 --- /dev/null +++ b/menu.js @@ -0,0 +1,136 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+='
    '; + for (var i in data.children) { + var url; + var link; + link = data.children[i].url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + } else { + url = relPath+link; + } + result+='
  • '+ + data.children[i].text+''+ + makeTree(data.children[i],relPath)+'
  • '; + } + result+='
'; + } + return result; + } + var searchBoxHtml; + if (searchEnabled) { + if (serverSide) { + searchBoxHtml='
'+ + '
'+ + '
 '+ + ''+ + '
'+ + '
'+ + '
'+ + '
'; + } else { + searchBoxHtml='
'+ + ''+ + ' '+ + ''+ + ''+ + ''+ + ''+ + ''+ + '
'; + } + } + + $('#main-nav').before('
'+ + ''+ + ''+ + '
'); + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchBoxHtml) { + $('#main-menu').append('
  • '); + } + var $mainMenuState = $('#main-menu-state'); + var prevWidth = 0; + if ($mainMenuState.length) { + function initResizableIfExists() { + if (typeof initResizable==='function') initResizable(); + } + // animate mobile menu + $mainMenuState.change(function(e) { + var $menu = $('#main-menu'); + var options = { duration: 250, step: initResizableIfExists }; + if (this.checked) { + options['complete'] = function() { $menu.css('display', 'block') }; + $menu.hide().slideDown(options); + } else { + options['complete'] = function() { $menu.css('display', 'none') }; + $menu.show().slideUp(options); + } + }); + // set default menu visibility + function resetState() { + var $menu = $('#main-menu'); + var $mainMenuState = $('#main-menu-state'); + var newWidth = $(window).outerWidth(); + if (newWidth!=prevWidth) { + if ($(window).outerWidth()<768) { + $mainMenuState.prop('checked',false); $menu.hide(); + $('#searchBoxPos1').html(searchBoxHtml); + $('#searchBoxPos2').hide(); + } else { + $menu.show(); + $('#searchBoxPos1').empty(); + $('#searchBoxPos2').html(searchBoxHtml); + $('#searchBoxPos2').show(); + } + if (typeof searchBox!=='undefined') { + searchBox.CloseResultsWindow(); + } + prevWidth = newWidth; + } + } + $(window).ready(function() { resetState(); initResizableIfExists(); }); + $(window).resize(resetState); + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/menudata.js b/menudata.js new file mode 100644 index 0000000..331865f --- /dev/null +++ b/menudata.js @@ -0,0 +1,66 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Hierarchy",url:"inherits.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"a",url:"functions.html#index_a"}, +{text:"c",url:"functions.html#index_c"}, +{text:"d",url:"functions.html#index_d"}, +{text:"e",url:"functions.html#index_e"}, +{text:"f",url:"functions.html#index_f"}, +{text:"g",url:"functions.html#index_g"}, +{text:"h",url:"functions.html#index_h"}, +{text:"i",url:"functions.html#index_i"}, +{text:"l",url:"functions.html#index_l"}, +{text:"o",url:"functions.html#index_o"}, +{text:"p",url:"functions.html#index_p"}, +{text:"r",url:"functions.html#index_r"}, +{text:"s",url:"functions.html#index_s"}, +{text:"t",url:"functions.html#index_t"}, +{text:"v",url:"functions.html#index_v"}, +{text:"~",url:"functions.html#index__7E"}]}, +{text:"Functions",url:"functions_func.html",children:[ +{text:"c",url:"functions_func.html#index_c"}, +{text:"d",url:"functions_func.html#index_d"}, +{text:"e",url:"functions_func.html#index_e"}, +{text:"f",url:"functions_func.html#index_f"}, +{text:"g",url:"functions_func.html#index_g"}, +{text:"i",url:"functions_func.html#index_i"}, +{text:"l",url:"functions_func.html#index_l"}, +{text:"o",url:"functions_func.html#index_o"}, +{text:"p",url:"functions_func.html#index_p"}, +{text:"r",url:"functions_func.html#index_r"}, +{text:"s",url:"functions_func.html#index_s"}, +{text:"t",url:"functions_func.html#index_t"}, +{text:"v",url:"functions_func.html#index_v"}, +{text:"~",url:"functions_func.html#index__7E"}]}, +{text:"Variables",url:"functions_vars.html"}]}]}, +{text:"Files",url:"files.html",children:[ +{text:"File List",url:"files.html"}]}]} diff --git a/minus.svg b/minus.svg new file mode 100644 index 0000000..f70d0c1 --- /dev/null +++ b/minus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/minusd.svg b/minusd.svg new file mode 100644 index 0000000..5f8e879 --- /dev/null +++ b/minusd.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/multiclass__strategy_8cpp_source.html b/multiclass__strategy_8cpp_source.html new file mode 100644 index 0000000..eb0b4bf --- /dev/null +++ b/multiclass__strategy_8cpp_source.html @@ -0,0 +1,587 @@ + + + + + + + +SVM Classifier C++: src/multiclass_strategy.cpp Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    multiclass_strategy.cpp
    +
    +
    +
    1#include "svm_classifier/multiclass_strategy.hpp"
    +
    2#include "svm.h" // libsvm
    +
    3#include "linear.h" // liblinear
    +
    4#include <algorithm>
    +
    5#include <unordered_map>
    +
    6#include <unordered_set>
    +
    7#include <chrono>
    +
    8#include <cmath>
    +
    9
    +
    10namespace svm_classifier {
    +
    11
    +
    12 // OneVsRestStrategy Implementation
    + +
    14 : library_type_(SVMLibrary::LIBLINEAR)
    +
    15 {
    +
    16 }
    +
    17
    +
    18 OneVsRestStrategy::~OneVsRestStrategy()
    +
    19 {
    +
    20 cleanup_models();
    +
    21 }
    +
    22
    +
    23 TrainingMetrics OneVsRestStrategy::fit(const torch::Tensor& X,
    +
    24 const torch::Tensor& y,
    +
    25 const KernelParameters& params,
    +
    26 DataConverter& converter)
    +
    27 {
    +
    28 cleanup_models();
    +
    29
    +
    30 auto start_time = std::chrono::high_resolution_clock::now();
    +
    31
    +
    32 // Store parameters and determine library type
    +
    33 params_ = params;
    +
    34 library_type_ = get_svm_library(params.get_kernel_type());
    +
    35
    +
    36 // Extract unique classes
    +
    37 auto y_cpu = y.to(torch::kCPU);
    +
    38 auto unique_classes_tensor = torch::unique(y_cpu);
    +
    39 classes_.clear();
    +
    40
    +
    41 for (int i = 0; i < unique_classes_tensor.size(0); ++i) {
    +
    42 classes_.push_back(unique_classes_tensor[i].item<int>());
    +
    43 }
    +
    44
    +
    45 std::sort(classes_.begin(), classes_.end());
    +
    46
    +
    47 // Handle binary classification case
    +
    48 if (classes_.size() <= 2) {
    +
    49 // For binary classification, train a single classifier
    +
    50 classes_.resize(2); // Ensure we have exactly 2 classes
    +
    51
    +
    52 auto binary_y = y;
    +
    53 if (classes_.size() == 1) {
    +
    54 // Edge case: only one class, create dummy binary problem
    +
    55 classes_.push_back(classes_[0] + 1);
    +
    56 binary_y = torch::cat({ y, torch::full({1}, classes_[1], y.options()) });
    +
    57 auto dummy_x = torch::zeros({ 1, X.size(1) }, X.options());
    +
    58 auto extended_X = torch::cat({ X, dummy_x });
    +
    59
    +
    60 double training_time = train_binary_classifier(extended_X, binary_y, params, converter, 0);
    +
    61 } else {
    +
    62 double training_time = train_binary_classifier(X, binary_y, params, converter, 0);
    +
    63 }
    +
    64 } else {
    +
    65 // Multiclass case: train one classifier per class
    +
    66 if (library_type_ == SVMLibrary::LIBSVM) {
    +
    67 svm_models_.resize(classes_.size());
    +
    68 } else {
    +
    69 linear_models_.resize(classes_.size());
    +
    70 }
    +
    71
    +
    72 double total_training_time = 0.0;
    +
    73
    +
    74 for (size_t i = 0; i < classes_.size(); ++i) {
    +
    75 auto binary_y = create_binary_labels(y, classes_[i]);
    +
    76 total_training_time += train_binary_classifier(X, binary_y, params, converter, i);
    +
    77 }
    +
    78 }
    +
    79
    +
    80 auto end_time = std::chrono::high_resolution_clock::now();
    +
    81 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    +
    82
    +
    83 is_trained_ = true;
    +
    84
    +
    85 TrainingMetrics metrics;
    +
    86 metrics.training_time = duration.count() / 1000.0;
    +
    87 metrics.status = TrainingStatus::SUCCESS;
    +
    88
    +
    89 return metrics;
    +
    90 }
    +
    91
    +
    92 std::vector<int> OneVsRestStrategy::predict(const torch::Tensor& X, DataConverter& converter)
    +
    93 {
    +
    94 if (!is_trained_) {
    +
    95 throw std::runtime_error("Model is not trained");
    +
    96 }
    +
    97
    +
    98 auto decision_values = decision_function(X, converter);
    +
    99 std::vector<int> predictions;
    +
    100 predictions.reserve(X.size(0));
    +
    101
    +
    102 for (const auto& decision_row : decision_values) {
    +
    103 // Find the class with maximum decision value
    +
    104 auto max_it = std::max_element(decision_row.begin(), decision_row.end());
    +
    105 int predicted_class_idx = std::distance(decision_row.begin(), max_it);
    +
    106 predictions.push_back(classes_[predicted_class_idx]);
    +
    107 }
    +
    108
    +
    109 return predictions;
    +
    110 }
    +
    111
    +
    112 std::vector<std::vector<double>> OneVsRestStrategy::predict_proba(const torch::Tensor& X,
    +
    113 DataConverter& converter)
    +
    114 {
    +
    115 if (!supports_probability()) {
    +
    116 throw std::runtime_error("Probability prediction not supported for current configuration");
    +
    117 }
    +
    118
    +
    119 if (!is_trained_) {
    +
    120 throw std::runtime_error("Model is not trained");
    +
    121 }
    +
    122
    +
    123 std::vector<std::vector<double>> probabilities;
    +
    124 probabilities.reserve(X.size(0));
    +
    125
    +
    126 for (int i = 0; i < X.size(0); ++i) {
    +
    127 auto sample = X[i];
    +
    128 std::vector<double> sample_probs;
    +
    129 sample_probs.reserve(classes_.size());
    +
    130
    +
    131 if (library_type_ == SVMLibrary::LIBSVM) {
    +
    132 for (size_t j = 0; j < classes_.size(); ++j) {
    +
    133 if (svm_models_[j]) {
    +
    134 auto sample_node = converter.to_svm_node(sample);
    +
    135 double prob_estimates[2];
    +
    136 svm_predict_probability(svm_models_[j].get(), sample_node, prob_estimates);
    +
    137 sample_probs.push_back(prob_estimates[0]); // Probability of positive class
    +
    138 } else {
    +
    139 sample_probs.push_back(0.0);
    +
    140 }
    +
    141 }
    +
    142 } else {
    +
    143 for (size_t j = 0; j < classes_.size(); ++j) {
    +
    144 if (linear_models_[j]) {
    +
    145 auto sample_node = converter.to_feature_node(sample);
    +
    146 double prob_estimates[2];
    +
    147 predict_probability(linear_models_[j].get(), sample_node, prob_estimates);
    +
    148 sample_probs.push_back(prob_estimates[0]); // Probability of positive class
    +
    149 } else {
    +
    150 sample_probs.push_back(0.0);
    +
    151 }
    +
    152 }
    +
    153 }
    +
    154
    +
    155 // Normalize probabilities
    +
    156 double sum = std::accumulate(sample_probs.begin(), sample_probs.end(), 0.0);
    +
    157 if (sum > 0.0) {
    +
    158 for (auto& prob : sample_probs) {
    +
    159 prob /= sum;
    +
    160 }
    +
    161 } else {
    +
    162 // Uniform distribution if all probabilities are zero
    +
    163 std::fill(sample_probs.begin(), sample_probs.end(), 1.0 / classes_.size());
    +
    164 }
    +
    165
    +
    166 probabilities.push_back(sample_probs);
    +
    167 }
    +
    168
    +
    169 return probabilities;
    +
    170 }
    +
    171
    +
    172 std::vector<std::vector<double>> OneVsRestStrategy::decision_function(const torch::Tensor& X,
    +
    173 DataConverter& converter)
    +
    174 {
    +
    175 if (!is_trained_) {
    +
    176 throw std::runtime_error("Model is not trained");
    +
    177 }
    +
    178
    +
    179 std::vector<std::vector<double>> decision_values;
    +
    180 decision_values.reserve(X.size(0));
    +
    181
    +
    182 for (int i = 0; i < X.size(0); ++i) {
    +
    183 auto sample = X[i];
    +
    184 std::vector<double> sample_decisions;
    +
    185 sample_decisions.reserve(classes_.size());
    +
    186
    +
    187 if (library_type_ == SVMLibrary::LIBSVM) {
    +
    188 for (size_t j = 0; j < classes_.size(); ++j) {
    +
    189 if (svm_models_[j]) {
    +
    190 auto sample_node = converter.to_svm_node(sample);
    +
    191 double decision_value;
    +
    192 svm_predict_values(svm_models_[j].get(), sample_node, &decision_value);
    +
    193 sample_decisions.push_back(decision_value);
    +
    194 } else {
    +
    195 sample_decisions.push_back(0.0);
    +
    196 }
    +
    197 }
    +
    198 } else {
    +
    199 for (size_t j = 0; j < classes_.size(); ++j) {
    +
    200 if (linear_models_[j]) {
    +
    201 auto sample_node = converter.to_feature_node(sample);
    +
    202 double decision_value;
    +
    203 predict_values(linear_models_[j].get(), sample_node, &decision_value);
    +
    204 sample_decisions.push_back(decision_value);
    +
    205 } else {
    +
    206 sample_decisions.push_back(0.0);
    +
    207 }
    +
    208 }
    +
    209 }
    +
    210
    +
    211 decision_values.push_back(sample_decisions);
    +
    212 }
    +
    213
    +
    214 return decision_values;
    +
    215 }
    +
    216
    +
    217 bool OneVsRestStrategy::supports_probability() const
    +
    218 {
    +
    219 if (!is_trained_) {
    +
    220 return params_.get_probability();
    +
    221 }
    +
    222
    +
    223 // Check if any model supports probability
    +
    224 if (library_type_ == SVMLibrary::LIBSVM) {
    +
    225 for (const auto& model : svm_models_) {
    +
    226 if (model && svm_check_probability_model(model.get())) {
    +
    227 return true;
    +
    228 }
    +
    229 }
    +
    230 } else {
    +
    231 for (const auto& model : linear_models_) {
    +
    232 if (model && check_probability_model(model.get())) {
    +
    233 return true;
    +
    234 }
    +
    235 }
    +
    236 }
    +
    237
    +
    238 return false;
    +
    239 }
    +
    240
    +
    241 torch::Tensor OneVsRestStrategy::create_binary_labels(const torch::Tensor& y, int positive_class)
    +
    242 {
    +
    243 auto binary_labels = torch::ones_like(y) * (-1); // Initialize with -1 (negative class)
    +
    244 auto positive_mask = (y == positive_class);
    +
    245 binary_labels.masked_fill_(positive_mask, 1); // Set positive class to +1
    +
    246
    +
    247 return binary_labels;
    +
    248 }
    +
    249
    +
    250 double OneVsRestStrategy::train_binary_classifier(const torch::Tensor& X,
    +
    251 const torch::Tensor& y_binary,
    +
    252 const KernelParameters& params,
    +
    253 DataConverter& converter,
    +
    254 int class_idx)
    +
    255 {
    +
    256 auto start_time = std::chrono::high_resolution_clock::now();
    +
    257
    +
    258 if (library_type_ == SVMLibrary::LIBSVM) {
    +
    259 // Use libsvm
    +
    260 auto problem = converter.to_svm_problem(X, y_binary);
    +
    261
    +
    262 // Setup SVM parameters
    +
    263 svm_parameter svm_params;
    +
    264 svm_params.svm_type = C_SVC;
    +
    265
    +
    266 switch (params.get_kernel_type()) {
    +
    267 case KernelType::RBF:
    +
    268 svm_params.kernel_type = RBF;
    +
    269 break;
    +
    270 case KernelType::POLYNOMIAL:
    +
    271 svm_params.kernel_type = POLY;
    +
    272 break;
    +
    273 case KernelType::SIGMOID:
    +
    274 svm_params.kernel_type = SIGMOID;
    +
    275 break;
    +
    276 default:
    +
    277 throw std::runtime_error("Invalid kernel type for libsvm");
    +
    278 }
    +
    279
    +
    280 svm_params.degree = params.get_degree();
    +
    281 svm_params.gamma = (params.get_gamma() == -1.0) ? 1.0 / X.size(1) : params.get_gamma();
    +
    282 svm_params.coef0 = params.get_coef0();
    +
    283 svm_params.cache_size = params.get_cache_size();
    +
    284 svm_params.eps = params.get_tolerance();
    +
    285 svm_params.C = params.get_C();
    +
    286 svm_params.nr_weight = 0;
    +
    287 svm_params.weight_label = nullptr;
    +
    288 svm_params.weight = nullptr;
    +
    289 svm_params.nu = 0.5;
    +
    290 svm_params.p = 0.1;
    +
    291 svm_params.shrinking = 1;
    +
    292 svm_params.probability = params.get_probability() ? 1 : 0;
    +
    293
    +
    294 // Check parameters
    +
    295 const char* error_msg = svm_check_parameter(problem.get(), &svm_params);
    +
    296 if (error_msg) {
    +
    297 throw std::runtime_error("SVM parameter error: " + std::string(error_msg));
    +
    298 }
    +
    299
    +
    300 // Train model
    +
    301 auto model = svm_train(problem.get(), &svm_params);
    +
    302 if (!model) {
    +
    303 throw std::runtime_error("Failed to train SVM model");
    +
    304 }
    +
    305
    +
    306 svm_models_[class_idx] = std::unique_ptr<svm_model>(model);
    +
    307
    +
    308 } else {
    +
    309 // Use liblinear
    +
    310 auto problem = converter.to_linear_problem(X, y_binary);
    +
    311
    +
    312 // Setup linear parameters
    +
    313 parameter linear_params;
    +
    314 linear_params.solver_type = L2R_L2LOSS_SVC_DUAL; // Default solver for C-SVC
    +
    315 linear_params.C = params.get_C();
    +
    316 linear_params.eps = params.get_tolerance();
    +
    317 linear_params.nr_weight = 0;
    +
    318 linear_params.weight_label = nullptr;
    +
    319 linear_params.weight = nullptr;
    +
    320 linear_params.p = 0.1;
    +
    321 linear_params.nu = 0.5;
    +
    322 linear_params.init_sol = nullptr;
    +
    323 linear_params.regularize_bias = 0;
    +
    324
    +
    325 // Check parameters
    +
    326 const char* error_msg = check_parameter(problem.get(), &linear_params);
    +
    327 if (error_msg) {
    +
    328 throw std::runtime_error("Linear parameter error: " + std::string(error_msg));
    +
    329 }
    +
    330
    +
    331 // Train model
    +
    332 auto model = train(problem.get(), &linear_params);
    +
    333 if (!model) {
    +
    334 throw std::runtime_error("Failed to train linear model");
    +
    335 }
    +
    336
    +
    337 linear_models_[class_idx] = std::unique_ptr<::model>(model);
    +
    338 }
    +
    339
    +
    340 auto end_time = std::chrono::high_resolution_clock::now();
    +
    341 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    +
    342
    +
    343 return duration.count() / 1000.0;
    +
    344 }
    +
    345
    +
    346 void OneVsRestStrategy::cleanup_models()
    +
    347 {
    +
    348 for (auto& model : svm_models_) {
    +
    349 if (model) {
    +
    350 svm_free_and_destroy_model(&model);
    +
    351 }
    +
    352 }
    +
    353 svm_models_.clear();
    +
    354
    +
    355 for (auto& model : linear_models_) {
    +
    356 if (model) {
    +
    357 free_and_destroy_model(&model);
    +
    358 }
    +
    359 }
    +
    360 linear_models_.clear();
    +
    361
    +
    362 is_trained_ = false;
    +
    363 }
    +
    364
    +
    365 // OneVsOneStrategy Implementation
    +
    366 OneVsOneStrategy::OneVsOneStrategy()
    +
    367 : library_type_(SVMLibrary::LIBLINEAR)
    +
    368 {
    +
    369 }
    +
    370
    +
    371 OneVsOneStrategy::~OneVsOneStrategy()
    +
    372 {
    +
    373 cleanup_models();
    +
    374 }
    +
    375
    +
    376 TrainingMetrics OneVsOneStrategy::fit(const torch::Tensor& X,
    +
    377 const torch::Tensor& y,
    +
    378 const KernelParameters& params,
    +
    379 DataConverter& converter)
    +
    380 {
    +
    381 cleanup_models();
    +
    382
    +
    383 auto start_time = std::chrono::high_resolution_clock::now();
    +
    384
    +
    385 // Store parameters and determine library type
    +
    386 params_ = params;
    +
    387 library_type_ = get_svm_library(params.get_kernel_type());
    +
    388
    +
    389 // Extract unique classes
    +
    390 auto y_cpu = y.to(torch::kCPU);
    +
    391 auto unique_classes_tensor = torch::unique(y_cpu);
    +
    392 classes_.clear();
    +
    393
    +
    394 for (int i = 0; i < unique_classes_tensor.size(0); ++i) {
    +
    395 classes_.push_back(unique_classes_tensor[i].item<int>());
    +
    396 }
    +
    397
    +
    398 std::sort(classes_.begin(), classes_.end());
    +
    399
    +
    400 // Generate all class pairs
    +
    401 class_pairs_.clear();
    +
    402 for (size_t i = 0; i < classes_.size(); ++i) {
    +
    403 for (size_t j = i + 1; j < classes_.size(); ++j) {
    +
    404 class_pairs_.emplace_back(classes_[i], classes_[j]);
    +
    405 }
    +
    406 }
    +
    407
    +
    408 // Initialize model storage
    +
    409 if (library_type_ == SVMLibrary::LIBSVM) {
    +
    410 svm_models_.resize(class_pairs_.size());
    +
    411 } else {
    +
    412 linear_models_.resize(class_pairs_.size());
    +
    413 }
    +
    414
    +
    415 double total_training_time = 0.0;
    +
    416
    +
    417 // Train one classifier for each class pair
    +
    418 for (size_t i = 0; i < class_pairs_.size(); ++i) {
    +
    419 auto [class1, class2] = class_pairs_[i];
    +
    420 total_training_time += train_pairwise_classifier(X, y, class1, class2, params, converter, i);
    +
    421 }
    +
    422
    +
    423 auto end_time = std::chrono::high_resolution_clock::now();
    +
    424 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    +
    425
    +
    426 is_trained_ = true;
    +
    427
    +
    428 TrainingMetrics metrics;
    +
    429 metrics.training_time = duration.count() / 1000.0;
    +
    430 metrics.status = TrainingStatus::SUCCESS;
    +
    431
    +
    432 return metrics;
    +
    433 }
    +
    434
    +
    435 std::vector<int> OneVsOneStrategy::predict(const torch::Tensor& X, DataConverter& converter)
    +
    436 {
    +
    437 if (!is_trained_) {
    +
    438 throw std::runtime_error("Model is not trained");
    +
    439 }
    +
    440
    +
    441 auto decision_values = decision_function(X, converter);
    +
    442 return vote_predictions(decision_values);
    +
    443 }
    +
    444
    +
    445 std::vector<std::vector<double>> OneVsOneStrategy::predict_proba(const torch::Tensor& X,
    +
    446 DataConverter& converter)
    +
    447 {
    +
    448 // OvO probability estimation is more complex and typically done via
    +
    449 // pairwise coupling (Hastie & Tibshirani, 1998)
    +
    450 // For simplicity, we'll use decision function values and normalize
    +
    451
    +
    452 auto decision_values = decision_function(X, converter);
    +
    453 std::vector<std::vector<double>> probabilities;
    +
    454 probabilities.reserve(X.size(0));
    +
    455
    +
    456 for (const auto& decision_row : decision_values) {
    +
    457 std::vector<double> class_scores(classes_.size(), 0.0);
    +
    458
    +
    459 // Aggregate decision values for each class
    +
    460 for (size_t i = 0; i < class_pairs_.size(); ++i) {
    +
    461 auto [class1, class2] = class_pairs_[i];
    +
    462 double decision = decision_row[i];
    +
    463
    +
    464 auto it1 = std::find(classes_.begin(), classes_.end(), class1);
    +
    465 auto it2 = std::find(classes_.begin(), classes_.end(), class2);
    +
    466
    +
    467 if (it1 != classes_.end() && it2 != classes_.end()) {
    +
    468 size_t idx1 = std::distance(classes_.begin(), it1);
    +
    469 size_t idx2 = std::distance(classes_.begin(), it2);
    +
    470
    +
    471 if (decision > 0) {
    +
    472 class_scores[idx1] += 1.0;
    +
    473 } else {
    +
    474 class_scores[idx2] += 1.0;
    +
    475 }
    +
    476 }
    +
    477 }
    +
    478
    +
    479 // Convert scores to probabilities
    +
    480 double sum = std::accumulate(class_scores.begin(), class_scores.end(), 0.0);
    +
    481 if (sum > 0.0) {
    +
    482 for (auto& score : class_scores) {
    +
    483 score /= sum;
    +
    484 }
    +
    485 } else {
    +
    486 std::fill(class_scores.begin(), class_scores.end(), 1.0 / classes_.size());
    +
    487 }
    +
    488
    +
    489 probabilities.push_back(class_scores);
    +
    490 }
    +
    491
    +
    492 return probabilities;
    +
    493 }
    +
    494
    +
    495 std::vector<std::vector<double>> OneVsOneStrategy::decision_function(const torch::Tensor& X,
    + +
    + + + + diff --git a/multiclass__strategy_8hpp_source.html b/multiclass__strategy_8hpp_source.html new file mode 100644 index 0000000..515192a --- /dev/null +++ b/multiclass__strategy_8hpp_source.html @@ -0,0 +1,281 @@ + + + + + + + +SVM Classifier C++: include/svm_classifier/multiclass_strategy.hpp Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    multiclass_strategy.hpp
    +
    +
    +
    1#pragma once
    +
    2
    +
    3#include "types.hpp"
    +
    4#include "kernel_parameters.hpp"
    +
    5#include "data_converter.hpp"
    +
    6#include <torch/torch.h>
    +
    7#include <vector>
    +
    8#include <memory>
    +
    9#include <unordered_map>
    +
    10
    +
    11// Forward declarations
    +
    12struct svm_model;
    +
    13struct model;
    +
    14
    +
    15namespace svm_classifier {
    +
    16
    +
    + +
    21 public:
    +
    25 virtual ~MulticlassStrategyBase() = default;
    +
    26
    +
    35 virtual TrainingMetrics fit(const torch::Tensor& X,
    +
    36 const torch::Tensor& y,
    +
    37 const KernelParameters& params,
    +
    38 DataConverter& converter) = 0;
    +
    39
    +
    46 virtual std::vector<int> predict(const torch::Tensor& X,
    +
    47 DataConverter& converter) = 0;
    +
    48
    +
    55 virtual std::vector<std::vector<double>> predict_proba(const torch::Tensor& X,
    +
    56 DataConverter& converter) = 0;
    +
    57
    +
    64 virtual std::vector<std::vector<double>> decision_function(const torch::Tensor& X,
    +
    65 DataConverter& converter) = 0;
    +
    66
    +
    71 virtual std::vector<int> get_classes() const = 0;
    +
    72
    +
    77 virtual bool supports_probability() const = 0;
    +
    78
    +
    83 virtual int get_n_classes() const = 0;
    +
    84
    +
    89 virtual MulticlassStrategy get_strategy_type() const = 0;
    +
    90
    +
    91 protected:
    +
    92 std::vector<int> classes_;
    +
    93 bool is_trained_ = false;
    +
    94 };
    +
    +
    95
    +
    + +
    100 public:
    + +
    105
    + +
    110
    +
    111 TrainingMetrics fit(const torch::Tensor& X,
    +
    112 const torch::Tensor& y,
    +
    113 const KernelParameters& params,
    +
    114 DataConverter& converter) override;
    +
    115
    +
    116 std::vector<int> predict(const torch::Tensor& X,
    +
    117 DataConverter& converter) override;
    +
    118
    +
    119 std::vector<std::vector<double>> predict_proba(const torch::Tensor& X,
    +
    120 DataConverter& converter) override;
    +
    121
    +
    122 std::vector<std::vector<double>> decision_function(const torch::Tensor& X,
    +
    123 DataConverter& converter) override;
    +
    124
    +
    125 std::vector<int> get_classes() const override { return classes_; }
    +
    126
    +
    127 bool supports_probability() const override;
    +
    128
    +
    129 int get_n_classes() const override { return static_cast<int>(classes_.size()); }
    +
    130
    +
    131 MulticlassStrategy get_strategy_type() const override { return MulticlassStrategy::ONE_VS_REST; }
    +
    132
    +
    133 private:
    +
    134 std::vector<std::unique_ptr<svm_model>> svm_models_;
    +
    135 std::vector<std::unique_ptr<model>> linear_models_;
    +
    136 KernelParameters params_;
    +
    137 SVMLibrary library_type_;
    +
    138
    +
    145 torch::Tensor create_binary_labels(const torch::Tensor& y, int positive_class);
    +
    146
    +
    156 double train_binary_classifier(const torch::Tensor& X,
    +
    157 const torch::Tensor& y_binary,
    +
    158 const KernelParameters& params,
    +
    159 DataConverter& converter,
    +
    160 int class_idx);
    +
    161
    +
    165 void cleanup_models();
    +
    166 };
    +
    +
    167
    +
    + +
    172 public:
    + +
    177
    + +
    182
    +
    183 TrainingMetrics fit(const torch::Tensor& X,
    +
    184 const torch::Tensor& y,
    +
    185 const KernelParameters& params,
    +
    186 DataConverter& converter) override;
    +
    187
    +
    188 std::vector<int> predict(const torch::Tensor& X,
    +
    189 DataConverter& converter) override;
    +
    190
    +
    191 std::vector<std::vector<double>> predict_proba(const torch::Tensor& X,
    +
    192 DataConverter& converter) override;
    +
    193
    +
    194 std::vector<std::vector<double>> decision_function(const torch::Tensor& X,
    +
    195 DataConverter& converter) override;
    +
    196
    +
    197 std::vector<int> get_classes() const override { return classes_; }
    +
    198
    +
    199 bool supports_probability() const override;
    +
    200
    +
    201 int get_n_classes() const override { return static_cast<int>(classes_.size()); }
    +
    202
    +
    203 MulticlassStrategy get_strategy_type() const override { return MulticlassStrategy::ONE_VS_ONE; }
    +
    204
    +
    205 private:
    +
    206 std::vector<std::unique_ptr<svm_model>> svm_models_;
    +
    207 std::vector<std::unique_ptr<model>> linear_models_;
    +
    208 std::vector<std::pair<int, int>> class_pairs_;
    +
    209 KernelParameters params_;
    +
    210 SVMLibrary library_type_;
    +
    211
    +
    220 std::pair<torch::Tensor, torch::Tensor> extract_binary_data(const torch::Tensor& X,
    +
    221 const torch::Tensor& y,
    +
    222 int class1,
    +
    223 int class2);
    +
    224
    +
    236 double train_pairwise_classifier(const torch::Tensor& X,
    +
    237 const torch::Tensor& y,
    +
    238 int class1,
    +
    239 int class2,
    +
    240 const KernelParameters& params,
    +
    241 DataConverter& converter,
    +
    242 int model_idx);
    +
    243
    +
    249 std::vector<int> vote_predictions(const std::vector<std::vector<double>>& decisions);
    +
    250
    +
    254 void cleanup_models();
    +
    255 };
    +
    +
    256
    +
    262 std::unique_ptr<MulticlassStrategyBase> create_multiclass_strategy(MulticlassStrategy strategy);
    +
    263
    +
    264} // namespace svm_classifier
    +
    Data converter between libtorch tensors and SVM library formats.
    +
    Abstract base class for multiclass classification strategies.
    +
    std::vector< int > classes_
    Unique class labels.
    +
    virtual int get_n_classes() const =0
    Get number of classes.
    +
    virtual bool supports_probability() const =0
    Check if the model supports probability prediction.
    +
    virtual MulticlassStrategy get_strategy_type() const =0
    Get strategy type.
    +
    virtual std::vector< int > get_classes() const =0
    Get unique class labels.
    +
    virtual TrainingMetrics fit(const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter)=0
    Train the multiclass classifier.
    +
    virtual std::vector< int > predict(const torch::Tensor &X, DataConverter &converter)=0
    Predict class labels.
    +
    virtual ~MulticlassStrategyBase()=default
    Virtual destructor.
    +
    bool is_trained_
    Whether the model is trained.
    +
    virtual std::vector< std::vector< double > > predict_proba(const torch::Tensor &X, DataConverter &converter)=0
    Predict class probabilities.
    +
    virtual std::vector< std::vector< double > > decision_function(const torch::Tensor &X, DataConverter &converter)=0
    Get decision function values.
    +
    One-vs-One (OvO) multiclass strategy.
    +
    int get_n_classes() const override
    Get number of classes.
    +
    std::vector< int > get_classes() const override
    Get unique class labels.
    +
    std::vector< std::vector< double > > decision_function(const torch::Tensor &X, DataConverter &converter) override
    Get decision function values.
    + +
    bool supports_probability() const override
    Check if the model supports probability prediction.
    +
    MulticlassStrategy get_strategy_type() const override
    Get strategy type.
    +
    std::vector< int > predict(const torch::Tensor &X, DataConverter &converter) override
    Predict class labels.
    +
    std::vector< std::vector< double > > predict_proba(const torch::Tensor &X, DataConverter &converter) override
    Predict class probabilities.
    +
    TrainingMetrics fit(const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter) override
    Train the multiclass classifier.
    +
    ~OneVsOneStrategy() override
    Destructor.
    +
    One-vs-Rest (OvR) multiclass strategy.
    +
    bool supports_probability() const override
    Check if the model supports probability prediction.
    + +
    int get_n_classes() const override
    Get number of classes.
    +
    std::vector< std::vector< double > > predict_proba(const torch::Tensor &X, DataConverter &converter) override
    Predict class probabilities.
    +
    std::vector< int > get_classes() const override
    Get unique class labels.
    +
    std::vector< int > predict(const torch::Tensor &X, DataConverter &converter) override
    Predict class labels.
    +
    std::vector< std::vector< double > > decision_function(const torch::Tensor &X, DataConverter &converter) override
    Get decision function values.
    +
    TrainingMetrics fit(const torch::Tensor &X, const torch::Tensor &y, const KernelParameters &params, DataConverter &converter) override
    Train the multiclass classifier.
    +
    ~OneVsRestStrategy() override
    Destructor.
    +
    MulticlassStrategy get_strategy_type() const override
    Get strategy type.
    +
    Training metrics structure.
    Definition types.hpp:59
    +
    + + + + diff --git a/nav_f.png b/nav_f.png new file mode 100644 index 0000000..72a58a5 Binary files /dev/null and b/nav_f.png differ diff --git a/nav_fd.png b/nav_fd.png new file mode 100644 index 0000000..032fbdd Binary files /dev/null and b/nav_fd.png differ diff --git a/nav_g.png b/nav_g.png new file mode 100644 index 0000000..2093a23 Binary files /dev/null and b/nav_g.png differ diff --git a/nav_h.png b/nav_h.png new file mode 100644 index 0000000..33389b1 Binary files /dev/null and b/nav_h.png differ diff --git a/nav_hd.png b/nav_hd.png new file mode 100644 index 0000000..de80f18 Binary files /dev/null and b/nav_hd.png differ diff --git a/open.png b/open.png new file mode 100644 index 0000000..30f75c7 Binary files /dev/null and b/open.png differ diff --git a/plus.svg b/plus.svg new file mode 100644 index 0000000..0752016 --- /dev/null +++ b/plus.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/plusd.svg b/plusd.svg new file mode 100644 index 0000000..0c65bfe --- /dev/null +++ b/plusd.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/search/all_0.js b/search/all_0.js new file mode 100644 index 0000000..e8048d6 --- /dev/null +++ b/search/all_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['accuracy_0',['accuracy',['../structsvm__classifier_1_1EvaluationMetrics.html#abe60e87c99b8b3c4499e602d8c26847a',1,'svm_classifier::EvaluationMetrics']]] +]; diff --git a/search/all_1.js b/search/all_1.js new file mode 100644 index 0000000..9e5fdc7 --- /dev/null +++ b/search/all_1.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['c_0',['SVM Classifier C++',['../index.html',1,'']]], + ['classes_5f_1',['classes_',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a15bb6eb53e91e604b259b3050bd40e27',1,'svm_classifier::MulticlassStrategyBase']]], + ['classifier_20c_2',['SVM Classifier C++',['../index.html',1,'']]], + ['cleanup_3',['cleanup',['../classsvm__classifier_1_1DataConverter.html#a46d12ba28c4c5bf6e0fad1122c621fa8',1,'svm_classifier::DataConverter::cleanup()'],['../classsvm__classifier_1_1DataConverter.html#a46d12ba28c4c5bf6e0fad1122c621fa8',1,'svm_classifier::DataConverter::cleanup()']]], + ['confusion_5fmatrix_4',['confusion_matrix',['../structsvm__classifier_1_1EvaluationMetrics.html#a843fbb476ae6bf24d7f72dabc3ef334a',1,'svm_classifier::EvaluationMetrics']]], + ['cross_5fvalidate_5',['cross_validate',['../classsvm__classifier_1_1SVMClassifier.html#a4c91072ea0d3d9b97ba458ff7d0898b8',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/all_10.js b/search/all_10.js new file mode 100644 index 0000000..5b05dc4 --- /dev/null +++ b/search/all_10.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['_7edataconverter_0',['~dataconverter',['../classsvm__classifier_1_1DataConverter.html#ac3af2c9c03cffe2968f29147611e333d',1,'svm_classifier::DataConverter::~DataConverter()'],['../classsvm__classifier_1_1DataConverter.html#ac3af2c9c03cffe2968f29147611e333d',1,'svm_classifier::DataConverter::~DataConverter()']]], + ['_7emulticlassstrategybase_1',['~MulticlassStrategyBase',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a8a5647dd57eed281288f0c9011b11395',1,'svm_classifier::MulticlassStrategyBase']]], + ['_7eonevsonestrategy_2',['~OneVsOneStrategy',['../classsvm__classifier_1_1OneVsOneStrategy.html#af9a653b62502e296d0d18092be56344f',1,'svm_classifier::OneVsOneStrategy']]], + ['_7eonevsreststrategy_3',['~OneVsRestStrategy',['../classsvm__classifier_1_1OneVsRestStrategy.html#acfd698dd6cc0a988ac642a00d1f0b970',1,'svm_classifier::OneVsRestStrategy']]], + ['_7esvmclassifier_4',['~SVMClassifier',['../classsvm__classifier_1_1SVMClassifier.html#a233584f6696969ce1a402624fd046146',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/all_2.js b/search/all_2.js new file mode 100644 index 0000000..e60b1b8 --- /dev/null +++ b/search/all_2.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['dataconverter_0',['dataconverter',['../classsvm__classifier_1_1DataConverter.html',1,'svm_classifier::DataConverter'],['../classsvm__classifier_1_1DataConverter.html#a5874904555f26448ed5ae4cf6f370056',1,'svm_classifier::DataConverter::DataConverter()'],['../classsvm__classifier_1_1DataConverter.html#a5874904555f26448ed5ae4cf6f370056',1,'svm_classifier::DataConverter::DataConverter()']]], + ['decision_5ffunction_1',['decision_function',['../classsvm__classifier_1_1MulticlassStrategyBase.html#ad1c4eb746cb1fdd67cf436ff85a9b0f0',1,'svm_classifier::MulticlassStrategyBase::decision_function()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a966b79bc8b6fac0fa78feefc2dd8a878',1,'svm_classifier::OneVsRestStrategy::decision_function()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a6aae0b5cd72180e94212454da8b777d2',1,'svm_classifier::OneVsOneStrategy::decision_function()'],['../classsvm__classifier_1_1SVMClassifier.html#ad153c0537998eae5fbca5fd0b5ead2b7',1,'svm_classifier::SVMClassifier::decision_function()']]], + ['decision_5fvalues_2',['decision_values',['../structsvm__classifier_1_1PredictionResult.html#a1ba501fdd3da8d3c4b99285b2f71c1d9',1,'svm_classifier::PredictionResult']]] +]; diff --git a/search/all_3.js b/search/all_3.js new file mode 100644 index 0000000..60557ca --- /dev/null +++ b/search/all_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['evaluate_0',['evaluate',['../classsvm__classifier_1_1SVMClassifier.html#a38a9b020b9f4f9254920c97a3a047e9b',1,'svm_classifier::SVMClassifier']]], + ['evaluationmetrics_1',['EvaluationMetrics',['../structsvm__classifier_1_1EvaluationMetrics.html',1,'svm_classifier']]] +]; diff --git a/search/all_4.js b/search/all_4.js new file mode 100644 index 0000000..e0400f3 --- /dev/null +++ b/search/all_4.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['f1_5fscore_0',['f1_score',['../structsvm__classifier_1_1EvaluationMetrics.html#a0eca4a2bc01318bb641f384abd0a47bc',1,'svm_classifier::EvaluationMetrics']]], + ['fit_1',['fit',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a548af7201b7970abee0c31e7ec07d896',1,'svm_classifier::MulticlassStrategyBase::fit()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#aae14da8c0effd04731b5a4a0181eb1b6',1,'svm_classifier::OneVsRestStrategy::fit()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#af5ce4aeb191c5feed178b6465eac66f6',1,'svm_classifier::OneVsOneStrategy::fit()'],['../classsvm__classifier_1_1SVMClassifier.html#a7e6648c4d2bac92bb00381076ea92db3',1,'svm_classifier::SVMClassifier::fit()']]], + ['from_5fdecision_5fvalues_2',['from_decision_values',['../classsvm__classifier_1_1DataConverter.html#a503eba54e8bb1f370e04b6e24354a32f',1,'svm_classifier::DataConverter::from_decision_values(const std::vector< std::vector< double > > &decision_values)'],['../classsvm__classifier_1_1DataConverter.html#a503eba54e8bb1f370e04b6e24354a32f',1,'svm_classifier::DataConverter::from_decision_values(const std::vector< std::vector< double > > &decision_values)']]], + ['from_5fpredictions_3',['from_predictions',['../classsvm__classifier_1_1DataConverter.html#ab3e800a5016a915e9912d5873bb48741',1,'svm_classifier::DataConverter::from_predictions(const std::vector< double > &predictions)'],['../classsvm__classifier_1_1DataConverter.html#ab3e800a5016a915e9912d5873bb48741',1,'svm_classifier::DataConverter::from_predictions(const std::vector< double > &predictions)']]], + ['from_5fprobabilities_4',['from_probabilities',['../classsvm__classifier_1_1DataConverter.html#a5460485675613c54596418af3d5057ff',1,'svm_classifier::DataConverter::from_probabilities(const std::vector< std::vector< double > > &probabilities)'],['../classsvm__classifier_1_1DataConverter.html#a5460485675613c54596418af3d5057ff',1,'svm_classifier::DataConverter::from_probabilities(const std::vector< std::vector< double > > &probabilities)']]] +]; diff --git a/search/all_5.js b/search/all_5.js new file mode 100644 index 0000000..cab837a --- /dev/null +++ b/search/all_5.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['get_5fclasses_0',['get_classes',['../classsvm__classifier_1_1OneVsRestStrategy.html#a5e10800b16dbc66fd1c0d5e0a42871f0',1,'svm_classifier::OneVsRestStrategy::get_classes()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a52f9c3d7d98077d1dec0d6034711b750',1,'svm_classifier::OneVsOneStrategy::get_classes()'],['../classsvm__classifier_1_1SVMClassifier.html#af0fea42cdfc9416ed854b0d4aefa82b9',1,'svm_classifier::SVMClassifier::get_classes()'],['../classsvm__classifier_1_1MulticlassStrategyBase.html#a379c4000227cc46410bfbecce6e80c33',1,'svm_classifier::MulticlassStrategyBase::get_classes()']]], + ['get_5ffeature_5fimportance_1',['get_feature_importance',['../classsvm__classifier_1_1SVMClassifier.html#a2ade33562381e34cbe4b04089545a715',1,'svm_classifier::SVMClassifier']]], + ['get_5fkernel_5ftype_2',['get_kernel_type',['../classsvm__classifier_1_1SVMClassifier.html#a55338ab396bd5da923b6acbef8ed783a',1,'svm_classifier::SVMClassifier']]], + ['get_5fmulticlass_5fstrategy_3',['get_multiclass_strategy',['../classsvm__classifier_1_1SVMClassifier.html#a14c2f7917c8a91154c09160288509f2c',1,'svm_classifier::SVMClassifier']]], + ['get_5fn_5fclasses_4',['get_n_classes',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a1740d877a4d634ec1763cb8646f5e172',1,'svm_classifier::MulticlassStrategyBase::get_n_classes()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a53abe89ec25c33fd9c32d92ba08d01ed',1,'svm_classifier::OneVsRestStrategy::get_n_classes()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a16ee2ae3623767af2165fef2d4b7d039',1,'svm_classifier::OneVsOneStrategy::get_n_classes()'],['../classsvm__classifier_1_1SVMClassifier.html#a75d501339e2e2273082b0838e9caadcd',1,'svm_classifier::SVMClassifier::get_n_classes()']]], + ['get_5fn_5ffeatures_5',['get_n_features',['../classsvm__classifier_1_1DataConverter.html#a26342a8cc8b943f099112040aa960ae6',1,'svm_classifier::DataConverter::get_n_features()'],['../classsvm__classifier_1_1SVMClassifier.html#a780afcb2ad618e46541aff8a44e9c7b4',1,'svm_classifier::SVMClassifier::get_n_features()'],['../classsvm__classifier_1_1DataConverter.html#a26342a8cc8b943f099112040aa960ae6',1,'svm_classifier::DataConverter::get_n_features() const']]], + ['get_5fn_5fsamples_6',['get_n_samples',['../classsvm__classifier_1_1DataConverter.html#a16999ded27bc2d42d2ebd9551b00c1cb',1,'svm_classifier::DataConverter::get_n_samples() const'],['../classsvm__classifier_1_1DataConverter.html#a16999ded27bc2d42d2ebd9551b00c1cb',1,'svm_classifier::DataConverter::get_n_samples() const']]], + ['get_5fparameters_7',['get_parameters',['../classsvm__classifier_1_1SVMClassifier.html#a7c39ec09b15186dcb4f04ae7171d23bb',1,'svm_classifier::SVMClassifier']]], + ['get_5fsparse_5fthreshold_8',['get_sparse_threshold',['../classsvm__classifier_1_1DataConverter.html#a1905f60fef9ffd3a8e8e45e41395352d',1,'svm_classifier::DataConverter::get_sparse_threshold() const'],['../classsvm__classifier_1_1DataConverter.html#a1905f60fef9ffd3a8e8e45e41395352d',1,'svm_classifier::DataConverter::get_sparse_threshold() const']]], + ['get_5fstrategy_5ftype_9',['get_strategy_type',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a31a0501fa1a6db1d41cbf825b2348e47',1,'svm_classifier::MulticlassStrategyBase::get_strategy_type()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#af9e1bd6d08ce3e7afd5279c835ce6cfb',1,'svm_classifier::OneVsRestStrategy::get_strategy_type()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#aae80b4e75459b2aca4f561d62c3c5675',1,'svm_classifier::OneVsOneStrategy::get_strategy_type()']]], + ['get_5fsvm_5flibrary_10',['get_svm_library',['../classsvm__classifier_1_1SVMClassifier.html#a38173e5cf0f6a4620f032fd54c28d592',1,'svm_classifier::SVMClassifier']]], + ['get_5ftraining_5fmetrics_11',['get_training_metrics',['../classsvm__classifier_1_1SVMClassifier.html#a0b8c77f81d84489b2da0d080773a2970',1,'svm_classifier::SVMClassifier']]], + ['grid_5fsearch_12',['grid_search',['../classsvm__classifier_1_1SVMClassifier.html#afed66a704dfb38cc7d080d3337d10194',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/all_6.js b/search/all_6.js new file mode 100644 index 0000000..6845fc3 --- /dev/null +++ b/search/all_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['has_5fprobabilities_0',['has_probabilities',['../structsvm__classifier_1_1PredictionResult.html#aeb863c05f5761ba1925166b73e3f4da6',1,'svm_classifier::PredictionResult']]] +]; diff --git a/search/all_7.js b/search/all_7.js new file mode 100644 index 0000000..2b85e2f --- /dev/null +++ b/search/all_7.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['is_5ffitted_0',['is_fitted',['../classsvm__classifier_1_1SVMClassifier.html#a71a85ab7893e7e2b40763db34096d8bb',1,'svm_classifier::SVMClassifier']]], + ['is_5ftrained_5f_1',['is_trained_',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a8e74cd580feaac0da34d204274a24fea',1,'svm_classifier::MulticlassStrategyBase']]], + ['iterations_2',['iterations',['../structsvm__classifier_1_1TrainingMetrics.html#a7ad692cf23590fe1be348902031bbc5a',1,'svm_classifier::TrainingMetrics']]] +]; diff --git a/search/all_8.js b/search/all_8.js new file mode 100644 index 0000000..7904640 --- /dev/null +++ b/search/all_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['load_5fmodel_0',['load_model',['../classsvm__classifier_1_1SVMClassifier.html#a583f5743acf5e6b850e079b9190989f1',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/all_9.js b/search/all_9.js new file mode 100644 index 0000000..1678293 --- /dev/null +++ b/search/all_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['multiclassstrategybase_0',['MulticlassStrategyBase',['../classsvm__classifier_1_1MulticlassStrategyBase.html',1,'svm_classifier']]] +]; diff --git a/search/all_a.js b/search/all_a.js new file mode 100644 index 0000000..5869c89 --- /dev/null +++ b/search/all_a.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['objective_5fvalue_0',['objective_value',['../structsvm__classifier_1_1TrainingMetrics.html#a1b41ef88d2dfb85b7f587292e6b83b7f',1,'svm_classifier::TrainingMetrics']]], + ['onevsonestrategy_1',['onevsonestrategy',['../classsvm__classifier_1_1OneVsOneStrategy.html',1,'svm_classifier::OneVsOneStrategy'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a6d4b060383169010dda4197a0bffa020',1,'svm_classifier::OneVsOneStrategy::OneVsOneStrategy()']]], + ['onevsreststrategy_2',['onevsreststrategy',['../classsvm__classifier_1_1OneVsRestStrategy.html',1,'svm_classifier::OneVsRestStrategy'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a30f146a564a9c9681524593cacbb43e7',1,'svm_classifier::OneVsRestStrategy::OneVsRestStrategy()']]], + ['operator_3d_3',['operator=',['../classsvm__classifier_1_1SVMClassifier.html#a209902805c75e8f22c55575adfedc7be',1,'svm_classifier::SVMClassifier::operator=(const SVMClassifier &)=delete'],['../classsvm__classifier_1_1SVMClassifier.html#a49b6a4a5ae8a8e0eaf24221482be3d6a',1,'svm_classifier::SVMClassifier::operator=(SVMClassifier &&) noexcept']]] +]; diff --git a/search/all_b.js b/search/all_b.js new file mode 100644 index 0000000..d3af9d2 --- /dev/null +++ b/search/all_b.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['precision_0',['precision',['../structsvm__classifier_1_1EvaluationMetrics.html#ad2ee81c9b36abcfb04598110402c242f',1,'svm_classifier::EvaluationMetrics']]], + ['predict_1',['predict',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a70f94cfcf8b2bf6d60133c688fe55f9d',1,'svm_classifier::MulticlassStrategyBase::predict()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a771903a821d5380ddd5d0b3a912e7df9',1,'svm_classifier::OneVsRestStrategy::predict()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#ab60df2d9b6069a73369b0bf9d3675662',1,'svm_classifier::OneVsOneStrategy::predict()'],['../classsvm__classifier_1_1SVMClassifier.html#a5c998d5574b3b6afe003b23ed02ed1d1',1,'svm_classifier::SVMClassifier::predict()']]], + ['predict_5fproba_2',['predict_proba',['../classsvm__classifier_1_1MulticlassStrategyBase.html#ab5348ee3b83547702ec7903ee7ee2da7',1,'svm_classifier::MulticlassStrategyBase::predict_proba()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a55639e5adaadcd6414b50d5ebf0d1cd2',1,'svm_classifier::OneVsRestStrategy::predict_proba()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#ae62e8b24115042d1119e76f3302f6992',1,'svm_classifier::OneVsOneStrategy::predict_proba()'],['../classsvm__classifier_1_1SVMClassifier.html#ab4ef3c839e085ece646cdd2501a51f67',1,'svm_classifier::SVMClassifier::predict_proba()']]], + ['predictionresult_3',['PredictionResult',['../structsvm__classifier_1_1PredictionResult.html',1,'svm_classifier']]], + ['predictions_4',['predictions',['../structsvm__classifier_1_1PredictionResult.html#a1a3e5f634777de08f2e6cd71ee4e8891',1,'svm_classifier::PredictionResult']]], + ['probabilities_5',['probabilities',['../structsvm__classifier_1_1PredictionResult.html#a22d86775346acc5545affd204eba47fd',1,'svm_classifier::PredictionResult']]] +]; diff --git a/search/all_c.js b/search/all_c.js new file mode 100644 index 0000000..f86fe37 --- /dev/null +++ b/search/all_c.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['recall_0',['recall',['../structsvm__classifier_1_1EvaluationMetrics.html#a78b1a0c50c4722bf73941a64e3a15e8f',1,'svm_classifier::EvaluationMetrics']]], + ['reset_1',['reset',['../classsvm__classifier_1_1SVMClassifier.html#aa2bd5715c9e54e3fb465a9bcbf2e9c8a',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/all_d.js b/search/all_d.js new file mode 100644 index 0000000..f321444 --- /dev/null +++ b/search/all_d.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['save_5fmodel_0',['save_model',['../classsvm__classifier_1_1SVMClassifier.html#ab8a0bd35705825e80a7567b576d47359',1,'svm_classifier::SVMClassifier']]], + ['score_1',['score',['../classsvm__classifier_1_1SVMClassifier.html#a0479c57489c14be4a5ca79368086f7f6',1,'svm_classifier::SVMClassifier']]], + ['set_5fparameters_2',['set_parameters',['../classsvm__classifier_1_1SVMClassifier.html#adb01e761fea07c709f3a0e315d3d0e06',1,'svm_classifier::SVMClassifier']]], + ['set_5fsparse_5fthreshold_3',['set_sparse_threshold',['../classsvm__classifier_1_1DataConverter.html#a9259322e54d2477478a684e99d8e557a',1,'svm_classifier::DataConverter::set_sparse_threshold(double threshold)'],['../classsvm__classifier_1_1DataConverter.html#a9259322e54d2477478a684e99d8e557a',1,'svm_classifier::DataConverter::set_sparse_threshold(double threshold)']]], + ['support_5fvectors_4',['support_vectors',['../structsvm__classifier_1_1TrainingMetrics.html#a3963a55a5d40a0e25d8ce94a5b81a227',1,'svm_classifier::TrainingMetrics']]], + ['supports_5fprobability_5',['supports_probability',['../classsvm__classifier_1_1OneVsRestStrategy.html#a200300198628ac119eac09e62ff62336',1,'svm_classifier::OneVsRestStrategy::supports_probability()'],['../classsvm__classifier_1_1SVMClassifier.html#a3f8b4e932f075b267507ad77a499a135',1,'svm_classifier::SVMClassifier::supports_probability()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a8875d29cb8666af10e0fb5634e08c0c1',1,'svm_classifier::OneVsOneStrategy::supports_probability()'],['../classsvm__classifier_1_1MulticlassStrategyBase.html#a2ab91902f8d6eb216f626ce9ea4be992',1,'svm_classifier::MulticlassStrategyBase::supports_probability()']]], + ['svm_20classifier_20c_6',['SVM Classifier C++',['../index.html',1,'']]], + ['svmclassifier_7',['svmclassifier',['../classsvm__classifier_1_1SVMClassifier.html',1,'svm_classifier::SVMClassifier'],['../classsvm__classifier_1_1SVMClassifier.html#a3ed45cdbc3fc5d947320177f42115dcf',1,'svm_classifier::SVMClassifier::SVMClassifier()'],['../classsvm__classifier_1_1SVMClassifier.html#a2afb41f77de4e8de6368d274a30191ec',1,'svm_classifier::SVMClassifier::SVMClassifier(const nlohmann::json &config)'],['../classsvm__classifier_1_1SVMClassifier.html#a90b2f18dd2cfeb23cf1375f265e22db0',1,'svm_classifier::SVMClassifier::SVMClassifier(KernelType kernel, double C=1.0, MulticlassStrategy multiclass_strategy=MulticlassStrategy::ONE_VS_REST)'],['../classsvm__classifier_1_1SVMClassifier.html#a377b6082ac4153be3197ef70c1c82984',1,'svm_classifier::SVMClassifier::SVMClassifier(const SVMClassifier &)=delete'],['../classsvm__classifier_1_1SVMClassifier.html#ae2eafdc66d1907c145efffd186dfff3f',1,'svm_classifier::SVMClassifier::SVMClassifier(SVMClassifier &&) noexcept']]] +]; diff --git a/search/all_e.js b/search/all_e.js new file mode 100644 index 0000000..23bb22b --- /dev/null +++ b/search/all_e.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['to_5ffeature_5fnode_0',['to_feature_node',['../classsvm__classifier_1_1DataConverter.html#a6bb2b4565b27df0db5f229dbd380795e',1,'svm_classifier::DataConverter::to_feature_node(const torch::Tensor &sample)'],['../classsvm__classifier_1_1DataConverter.html#a6bb2b4565b27df0db5f229dbd380795e',1,'svm_classifier::DataConverter::to_feature_node(const torch::Tensor &sample)']]], + ['to_5flinear_5fproblem_1',['to_linear_problem',['../classsvm__classifier_1_1DataConverter.html#a7e7d8f6102b7a9b3256ff0dc6f536a35',1,'svm_classifier::DataConverter::to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())'],['../classsvm__classifier_1_1DataConverter.html#a7e7d8f6102b7a9b3256ff0dc6f536a35',1,'svm_classifier::DataConverter::to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())']]], + ['to_5fsvm_5fnode_2',['to_svm_node',['../classsvm__classifier_1_1DataConverter.html#a16e1539ef1266ca9ddd27a2ac5a53b92',1,'svm_classifier::DataConverter::to_svm_node(const torch::Tensor &sample)'],['../classsvm__classifier_1_1DataConverter.html#a16e1539ef1266ca9ddd27a2ac5a53b92',1,'svm_classifier::DataConverter::to_svm_node(const torch::Tensor &sample)']]], + ['to_5fsvm_5fproblem_3',['to_svm_problem',['../classsvm__classifier_1_1DataConverter.html#a66f446e4decfe47bbba37c789f03f729',1,'svm_classifier::DataConverter::to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())'],['../classsvm__classifier_1_1DataConverter.html#a66f446e4decfe47bbba37c789f03f729',1,'svm_classifier::DataConverter::to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())']]], + ['training_5ftime_4',['training_time',['../structsvm__classifier_1_1TrainingMetrics.html#af8eee57134f3fe0fab23b60fe33cb4de',1,'svm_classifier::TrainingMetrics']]], + ['trainingmetrics_5',['TrainingMetrics',['../structsvm__classifier_1_1TrainingMetrics.html',1,'svm_classifier']]] +]; diff --git a/search/all_f.js b/search/all_f.js new file mode 100644 index 0000000..85e487a --- /dev/null +++ b/search/all_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['validate_5ftensors_0',['validate_tensors',['../classsvm__classifier_1_1DataConverter.html#aa0615f3de29958b2c5229d349f2f60ce',1,'svm_classifier::DataConverter::validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())'],['../classsvm__classifier_1_1DataConverter.html#aa0615f3de29958b2c5229d349f2f60ce',1,'svm_classifier::DataConverter::validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())']]] +]; diff --git a/search/classes_0.js b/search/classes_0.js new file mode 100644 index 0000000..58c3f7a --- /dev/null +++ b/search/classes_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['dataconverter_0',['DataConverter',['../classsvm__classifier_1_1DataConverter.html',1,'svm_classifier']]] +]; diff --git a/search/classes_1.js b/search/classes_1.js new file mode 100644 index 0000000..69ed63f --- /dev/null +++ b/search/classes_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['evaluationmetrics_0',['EvaluationMetrics',['../structsvm__classifier_1_1EvaluationMetrics.html',1,'svm_classifier']]] +]; diff --git a/search/classes_2.js b/search/classes_2.js new file mode 100644 index 0000000..1678293 --- /dev/null +++ b/search/classes_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['multiclassstrategybase_0',['MulticlassStrategyBase',['../classsvm__classifier_1_1MulticlassStrategyBase.html',1,'svm_classifier']]] +]; diff --git a/search/classes_3.js b/search/classes_3.js new file mode 100644 index 0000000..9b7cf65 --- /dev/null +++ b/search/classes_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['onevsonestrategy_0',['OneVsOneStrategy',['../classsvm__classifier_1_1OneVsOneStrategy.html',1,'svm_classifier']]], + ['onevsreststrategy_1',['OneVsRestStrategy',['../classsvm__classifier_1_1OneVsRestStrategy.html',1,'svm_classifier']]] +]; diff --git a/search/classes_4.js b/search/classes_4.js new file mode 100644 index 0000000..7c54cdf --- /dev/null +++ b/search/classes_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['predictionresult_0',['PredictionResult',['../structsvm__classifier_1_1PredictionResult.html',1,'svm_classifier']]] +]; diff --git a/search/classes_5.js b/search/classes_5.js new file mode 100644 index 0000000..c397b22 --- /dev/null +++ b/search/classes_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['svmclassifier_0',['SVMClassifier',['../classsvm__classifier_1_1SVMClassifier.html',1,'svm_classifier']]] +]; diff --git a/search/classes_6.js b/search/classes_6.js new file mode 100644 index 0000000..9ef7f7e --- /dev/null +++ b/search/classes_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['trainingmetrics_0',['TrainingMetrics',['../structsvm__classifier_1_1TrainingMetrics.html',1,'svm_classifier']]] +]; diff --git a/search/close.svg b/search/close.svg new file mode 100644 index 0000000..337d6cc --- /dev/null +++ b/search/close.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/search/functions_0.js b/search/functions_0.js new file mode 100644 index 0000000..c17e9e9 --- /dev/null +++ b/search/functions_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['cleanup_0',['cleanup',['../classsvm__classifier_1_1DataConverter.html#a46d12ba28c4c5bf6e0fad1122c621fa8',1,'svm_classifier::DataConverter::cleanup()'],['../classsvm__classifier_1_1DataConverter.html#a46d12ba28c4c5bf6e0fad1122c621fa8',1,'svm_classifier::DataConverter::cleanup()']]], + ['cross_5fvalidate_1',['cross_validate',['../classsvm__classifier_1_1SVMClassifier.html#a4c91072ea0d3d9b97ba458ff7d0898b8',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/functions_1.js b/search/functions_1.js new file mode 100644 index 0000000..3a6a7e9 --- /dev/null +++ b/search/functions_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['dataconverter_0',['dataconverter',['../classsvm__classifier_1_1DataConverter.html#a5874904555f26448ed5ae4cf6f370056',1,'svm_classifier::DataConverter::DataConverter()'],['../classsvm__classifier_1_1DataConverter.html#a5874904555f26448ed5ae4cf6f370056',1,'svm_classifier::DataConverter::DataConverter()']]], + ['decision_5ffunction_1',['decision_function',['../classsvm__classifier_1_1MulticlassStrategyBase.html#ad1c4eb746cb1fdd67cf436ff85a9b0f0',1,'svm_classifier::MulticlassStrategyBase::decision_function()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a966b79bc8b6fac0fa78feefc2dd8a878',1,'svm_classifier::OneVsRestStrategy::decision_function()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a6aae0b5cd72180e94212454da8b777d2',1,'svm_classifier::OneVsOneStrategy::decision_function()'],['../classsvm__classifier_1_1SVMClassifier.html#ad153c0537998eae5fbca5fd0b5ead2b7',1,'svm_classifier::SVMClassifier::decision_function()']]] +]; diff --git a/search/functions_2.js b/search/functions_2.js new file mode 100644 index 0000000..b98bdfc --- /dev/null +++ b/search/functions_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['evaluate_0',['evaluate',['../classsvm__classifier_1_1SVMClassifier.html#a38a9b020b9f4f9254920c97a3a047e9b',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/functions_3.js b/search/functions_3.js new file mode 100644 index 0000000..b56519f --- /dev/null +++ b/search/functions_3.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['fit_0',['fit',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a548af7201b7970abee0c31e7ec07d896',1,'svm_classifier::MulticlassStrategyBase::fit()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#aae14da8c0effd04731b5a4a0181eb1b6',1,'svm_classifier::OneVsRestStrategy::fit()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#af5ce4aeb191c5feed178b6465eac66f6',1,'svm_classifier::OneVsOneStrategy::fit()'],['../classsvm__classifier_1_1SVMClassifier.html#a7e6648c4d2bac92bb00381076ea92db3',1,'svm_classifier::SVMClassifier::fit()']]], + ['from_5fdecision_5fvalues_1',['from_decision_values',['../classsvm__classifier_1_1DataConverter.html#a503eba54e8bb1f370e04b6e24354a32f',1,'svm_classifier::DataConverter::from_decision_values(const std::vector< std::vector< double > > &decision_values)'],['../classsvm__classifier_1_1DataConverter.html#a503eba54e8bb1f370e04b6e24354a32f',1,'svm_classifier::DataConverter::from_decision_values(const std::vector< std::vector< double > > &decision_values)']]], + ['from_5fpredictions_2',['from_predictions',['../classsvm__classifier_1_1DataConverter.html#ab3e800a5016a915e9912d5873bb48741',1,'svm_classifier::DataConverter::from_predictions(const std::vector< double > &predictions)'],['../classsvm__classifier_1_1DataConverter.html#ab3e800a5016a915e9912d5873bb48741',1,'svm_classifier::DataConverter::from_predictions(const std::vector< double > &predictions)']]], + ['from_5fprobabilities_3',['from_probabilities',['../classsvm__classifier_1_1DataConverter.html#a5460485675613c54596418af3d5057ff',1,'svm_classifier::DataConverter::from_probabilities(const std::vector< std::vector< double > > &probabilities)'],['../classsvm__classifier_1_1DataConverter.html#a5460485675613c54596418af3d5057ff',1,'svm_classifier::DataConverter::from_probabilities(const std::vector< std::vector< double > > &probabilities)']]] +]; diff --git a/search/functions_4.js b/search/functions_4.js new file mode 100644 index 0000000..cab837a --- /dev/null +++ b/search/functions_4.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['get_5fclasses_0',['get_classes',['../classsvm__classifier_1_1OneVsRestStrategy.html#a5e10800b16dbc66fd1c0d5e0a42871f0',1,'svm_classifier::OneVsRestStrategy::get_classes()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a52f9c3d7d98077d1dec0d6034711b750',1,'svm_classifier::OneVsOneStrategy::get_classes()'],['../classsvm__classifier_1_1SVMClassifier.html#af0fea42cdfc9416ed854b0d4aefa82b9',1,'svm_classifier::SVMClassifier::get_classes()'],['../classsvm__classifier_1_1MulticlassStrategyBase.html#a379c4000227cc46410bfbecce6e80c33',1,'svm_classifier::MulticlassStrategyBase::get_classes()']]], + ['get_5ffeature_5fimportance_1',['get_feature_importance',['../classsvm__classifier_1_1SVMClassifier.html#a2ade33562381e34cbe4b04089545a715',1,'svm_classifier::SVMClassifier']]], + ['get_5fkernel_5ftype_2',['get_kernel_type',['../classsvm__classifier_1_1SVMClassifier.html#a55338ab396bd5da923b6acbef8ed783a',1,'svm_classifier::SVMClassifier']]], + ['get_5fmulticlass_5fstrategy_3',['get_multiclass_strategy',['../classsvm__classifier_1_1SVMClassifier.html#a14c2f7917c8a91154c09160288509f2c',1,'svm_classifier::SVMClassifier']]], + ['get_5fn_5fclasses_4',['get_n_classes',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a1740d877a4d634ec1763cb8646f5e172',1,'svm_classifier::MulticlassStrategyBase::get_n_classes()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a53abe89ec25c33fd9c32d92ba08d01ed',1,'svm_classifier::OneVsRestStrategy::get_n_classes()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a16ee2ae3623767af2165fef2d4b7d039',1,'svm_classifier::OneVsOneStrategy::get_n_classes()'],['../classsvm__classifier_1_1SVMClassifier.html#a75d501339e2e2273082b0838e9caadcd',1,'svm_classifier::SVMClassifier::get_n_classes()']]], + ['get_5fn_5ffeatures_5',['get_n_features',['../classsvm__classifier_1_1DataConverter.html#a26342a8cc8b943f099112040aa960ae6',1,'svm_classifier::DataConverter::get_n_features()'],['../classsvm__classifier_1_1SVMClassifier.html#a780afcb2ad618e46541aff8a44e9c7b4',1,'svm_classifier::SVMClassifier::get_n_features()'],['../classsvm__classifier_1_1DataConverter.html#a26342a8cc8b943f099112040aa960ae6',1,'svm_classifier::DataConverter::get_n_features() const']]], + ['get_5fn_5fsamples_6',['get_n_samples',['../classsvm__classifier_1_1DataConverter.html#a16999ded27bc2d42d2ebd9551b00c1cb',1,'svm_classifier::DataConverter::get_n_samples() const'],['../classsvm__classifier_1_1DataConverter.html#a16999ded27bc2d42d2ebd9551b00c1cb',1,'svm_classifier::DataConverter::get_n_samples() const']]], + ['get_5fparameters_7',['get_parameters',['../classsvm__classifier_1_1SVMClassifier.html#a7c39ec09b15186dcb4f04ae7171d23bb',1,'svm_classifier::SVMClassifier']]], + ['get_5fsparse_5fthreshold_8',['get_sparse_threshold',['../classsvm__classifier_1_1DataConverter.html#a1905f60fef9ffd3a8e8e45e41395352d',1,'svm_classifier::DataConverter::get_sparse_threshold() const'],['../classsvm__classifier_1_1DataConverter.html#a1905f60fef9ffd3a8e8e45e41395352d',1,'svm_classifier::DataConverter::get_sparse_threshold() const']]], + ['get_5fstrategy_5ftype_9',['get_strategy_type',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a31a0501fa1a6db1d41cbf825b2348e47',1,'svm_classifier::MulticlassStrategyBase::get_strategy_type()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#af9e1bd6d08ce3e7afd5279c835ce6cfb',1,'svm_classifier::OneVsRestStrategy::get_strategy_type()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#aae80b4e75459b2aca4f561d62c3c5675',1,'svm_classifier::OneVsOneStrategy::get_strategy_type()']]], + ['get_5fsvm_5flibrary_10',['get_svm_library',['../classsvm__classifier_1_1SVMClassifier.html#a38173e5cf0f6a4620f032fd54c28d592',1,'svm_classifier::SVMClassifier']]], + ['get_5ftraining_5fmetrics_11',['get_training_metrics',['../classsvm__classifier_1_1SVMClassifier.html#a0b8c77f81d84489b2da0d080773a2970',1,'svm_classifier::SVMClassifier']]], + ['grid_5fsearch_12',['grid_search',['../classsvm__classifier_1_1SVMClassifier.html#afed66a704dfb38cc7d080d3337d10194',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/functions_5.js b/search/functions_5.js new file mode 100644 index 0000000..a04621f --- /dev/null +++ b/search/functions_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['is_5ffitted_0',['is_fitted',['../classsvm__classifier_1_1SVMClassifier.html#a71a85ab7893e7e2b40763db34096d8bb',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/functions_6.js b/search/functions_6.js new file mode 100644 index 0000000..7904640 --- /dev/null +++ b/search/functions_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['load_5fmodel_0',['load_model',['../classsvm__classifier_1_1SVMClassifier.html#a583f5743acf5e6b850e079b9190989f1',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/functions_7.js b/search/functions_7.js new file mode 100644 index 0000000..520e4f9 --- /dev/null +++ b/search/functions_7.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['onevsonestrategy_0',['OneVsOneStrategy',['../classsvm__classifier_1_1OneVsOneStrategy.html#a6d4b060383169010dda4197a0bffa020',1,'svm_classifier::OneVsOneStrategy']]], + ['onevsreststrategy_1',['OneVsRestStrategy',['../classsvm__classifier_1_1OneVsRestStrategy.html#a30f146a564a9c9681524593cacbb43e7',1,'svm_classifier::OneVsRestStrategy']]], + ['operator_3d_2',['operator=',['../classsvm__classifier_1_1SVMClassifier.html#a209902805c75e8f22c55575adfedc7be',1,'svm_classifier::SVMClassifier::operator=(const SVMClassifier &)=delete'],['../classsvm__classifier_1_1SVMClassifier.html#a49b6a4a5ae8a8e0eaf24221482be3d6a',1,'svm_classifier::SVMClassifier::operator=(SVMClassifier &&) noexcept']]] +]; diff --git a/search/functions_8.js b/search/functions_8.js new file mode 100644 index 0000000..c644184 --- /dev/null +++ b/search/functions_8.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['predict_0',['predict',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a70f94cfcf8b2bf6d60133c688fe55f9d',1,'svm_classifier::MulticlassStrategyBase::predict()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a771903a821d5380ddd5d0b3a912e7df9',1,'svm_classifier::OneVsRestStrategy::predict()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#ab60df2d9b6069a73369b0bf9d3675662',1,'svm_classifier::OneVsOneStrategy::predict()'],['../classsvm__classifier_1_1SVMClassifier.html#a5c998d5574b3b6afe003b23ed02ed1d1',1,'svm_classifier::SVMClassifier::predict()']]], + ['predict_5fproba_1',['predict_proba',['../classsvm__classifier_1_1MulticlassStrategyBase.html#ab5348ee3b83547702ec7903ee7ee2da7',1,'svm_classifier::MulticlassStrategyBase::predict_proba()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a55639e5adaadcd6414b50d5ebf0d1cd2',1,'svm_classifier::OneVsRestStrategy::predict_proba()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#ae62e8b24115042d1119e76f3302f6992',1,'svm_classifier::OneVsOneStrategy::predict_proba()'],['../classsvm__classifier_1_1SVMClassifier.html#ab4ef3c839e085ece646cdd2501a51f67',1,'svm_classifier::SVMClassifier::predict_proba()']]] +]; diff --git a/search/functions_9.js b/search/functions_9.js new file mode 100644 index 0000000..7610989 --- /dev/null +++ b/search/functions_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['reset_0',['reset',['../classsvm__classifier_1_1SVMClassifier.html#aa2bd5715c9e54e3fb465a9bcbf2e9c8a',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/functions_a.js b/search/functions_a.js new file mode 100644 index 0000000..ec50248 --- /dev/null +++ b/search/functions_a.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['save_5fmodel_0',['save_model',['../classsvm__classifier_1_1SVMClassifier.html#ab8a0bd35705825e80a7567b576d47359',1,'svm_classifier::SVMClassifier']]], + ['score_1',['score',['../classsvm__classifier_1_1SVMClassifier.html#a0479c57489c14be4a5ca79368086f7f6',1,'svm_classifier::SVMClassifier']]], + ['set_5fparameters_2',['set_parameters',['../classsvm__classifier_1_1SVMClassifier.html#adb01e761fea07c709f3a0e315d3d0e06',1,'svm_classifier::SVMClassifier']]], + ['set_5fsparse_5fthreshold_3',['set_sparse_threshold',['../classsvm__classifier_1_1DataConverter.html#a9259322e54d2477478a684e99d8e557a',1,'svm_classifier::DataConverter::set_sparse_threshold(double threshold)'],['../classsvm__classifier_1_1DataConverter.html#a9259322e54d2477478a684e99d8e557a',1,'svm_classifier::DataConverter::set_sparse_threshold(double threshold)']]], + ['supports_5fprobability_4',['supports_probability',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a2ab91902f8d6eb216f626ce9ea4be992',1,'svm_classifier::MulticlassStrategyBase::supports_probability()'],['../classsvm__classifier_1_1OneVsRestStrategy.html#a200300198628ac119eac09e62ff62336',1,'svm_classifier::OneVsRestStrategy::supports_probability()'],['../classsvm__classifier_1_1OneVsOneStrategy.html#a8875d29cb8666af10e0fb5634e08c0c1',1,'svm_classifier::OneVsOneStrategy::supports_probability()'],['../classsvm__classifier_1_1SVMClassifier.html#a3f8b4e932f075b267507ad77a499a135',1,'svm_classifier::SVMClassifier::supports_probability() const']]], + ['svmclassifier_5',['svmclassifier',['../classsvm__classifier_1_1SVMClassifier.html#a3ed45cdbc3fc5d947320177f42115dcf',1,'svm_classifier::SVMClassifier::SVMClassifier()'],['../classsvm__classifier_1_1SVMClassifier.html#a2afb41f77de4e8de6368d274a30191ec',1,'svm_classifier::SVMClassifier::SVMClassifier(const nlohmann::json &config)'],['../classsvm__classifier_1_1SVMClassifier.html#a90b2f18dd2cfeb23cf1375f265e22db0',1,'svm_classifier::SVMClassifier::SVMClassifier(KernelType kernel, double C=1.0, MulticlassStrategy multiclass_strategy=MulticlassStrategy::ONE_VS_REST)'],['../classsvm__classifier_1_1SVMClassifier.html#a377b6082ac4153be3197ef70c1c82984',1,'svm_classifier::SVMClassifier::SVMClassifier(const SVMClassifier &)=delete'],['../classsvm__classifier_1_1SVMClassifier.html#ae2eafdc66d1907c145efffd186dfff3f',1,'svm_classifier::SVMClassifier::SVMClassifier(SVMClassifier &&) noexcept']]] +]; diff --git a/search/functions_b.js b/search/functions_b.js new file mode 100644 index 0000000..9a5376a --- /dev/null +++ b/search/functions_b.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['to_5ffeature_5fnode_0',['to_feature_node',['../classsvm__classifier_1_1DataConverter.html#a6bb2b4565b27df0db5f229dbd380795e',1,'svm_classifier::DataConverter::to_feature_node(const torch::Tensor &sample)'],['../classsvm__classifier_1_1DataConverter.html#a6bb2b4565b27df0db5f229dbd380795e',1,'svm_classifier::DataConverter::to_feature_node(const torch::Tensor &sample)']]], + ['to_5flinear_5fproblem_1',['to_linear_problem',['../classsvm__classifier_1_1DataConverter.html#a7e7d8f6102b7a9b3256ff0dc6f536a35',1,'svm_classifier::DataConverter::to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())'],['../classsvm__classifier_1_1DataConverter.html#a7e7d8f6102b7a9b3256ff0dc6f536a35',1,'svm_classifier::DataConverter::to_linear_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())']]], + ['to_5fsvm_5fnode_2',['to_svm_node',['../classsvm__classifier_1_1DataConverter.html#a16e1539ef1266ca9ddd27a2ac5a53b92',1,'svm_classifier::DataConverter::to_svm_node(const torch::Tensor &sample)'],['../classsvm__classifier_1_1DataConverter.html#a16e1539ef1266ca9ddd27a2ac5a53b92',1,'svm_classifier::DataConverter::to_svm_node(const torch::Tensor &sample)']]], + ['to_5fsvm_5fproblem_3',['to_svm_problem',['../classsvm__classifier_1_1DataConverter.html#a66f446e4decfe47bbba37c789f03f729',1,'svm_classifier::DataConverter::to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())'],['../classsvm__classifier_1_1DataConverter.html#a66f446e4decfe47bbba37c789f03f729',1,'svm_classifier::DataConverter::to_svm_problem(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())']]] +]; diff --git a/search/functions_c.js b/search/functions_c.js new file mode 100644 index 0000000..85e487a --- /dev/null +++ b/search/functions_c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['validate_5ftensors_0',['validate_tensors',['../classsvm__classifier_1_1DataConverter.html#aa0615f3de29958b2c5229d349f2f60ce',1,'svm_classifier::DataConverter::validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())'],['../classsvm__classifier_1_1DataConverter.html#aa0615f3de29958b2c5229d349f2f60ce',1,'svm_classifier::DataConverter::validate_tensors(const torch::Tensor &X, const torch::Tensor &y=torch::Tensor())']]] +]; diff --git a/search/functions_d.js b/search/functions_d.js new file mode 100644 index 0000000..5b05dc4 --- /dev/null +++ b/search/functions_d.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['_7edataconverter_0',['~dataconverter',['../classsvm__classifier_1_1DataConverter.html#ac3af2c9c03cffe2968f29147611e333d',1,'svm_classifier::DataConverter::~DataConverter()'],['../classsvm__classifier_1_1DataConverter.html#ac3af2c9c03cffe2968f29147611e333d',1,'svm_classifier::DataConverter::~DataConverter()']]], + ['_7emulticlassstrategybase_1',['~MulticlassStrategyBase',['../classsvm__classifier_1_1MulticlassStrategyBase.html#a8a5647dd57eed281288f0c9011b11395',1,'svm_classifier::MulticlassStrategyBase']]], + ['_7eonevsonestrategy_2',['~OneVsOneStrategy',['../classsvm__classifier_1_1OneVsOneStrategy.html#af9a653b62502e296d0d18092be56344f',1,'svm_classifier::OneVsOneStrategy']]], + ['_7eonevsreststrategy_3',['~OneVsRestStrategy',['../classsvm__classifier_1_1OneVsRestStrategy.html#acfd698dd6cc0a988ac642a00d1f0b970',1,'svm_classifier::OneVsRestStrategy']]], + ['_7esvmclassifier_4',['~SVMClassifier',['../classsvm__classifier_1_1SVMClassifier.html#a233584f6696969ce1a402624fd046146',1,'svm_classifier::SVMClassifier']]] +]; diff --git a/search/mag.svg b/search/mag.svg new file mode 100644 index 0000000..ffb6cf0 --- /dev/null +++ b/search/mag.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/search/mag_d.svg b/search/mag_d.svg new file mode 100644 index 0000000..4122773 --- /dev/null +++ b/search/mag_d.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/search/mag_sel.svg b/search/mag_sel.svg new file mode 100644 index 0000000..553dba8 --- /dev/null +++ b/search/mag_sel.svg @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/search/mag_seld.svg b/search/mag_seld.svg new file mode 100644 index 0000000..c906f84 --- /dev/null +++ b/search/mag_seld.svg @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/search/pages_0.js b/search/pages_0.js new file mode 100644 index 0000000..126a80f --- /dev/null +++ b/search/pages_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['c_0',['SVM Classifier C++',['../index.html',1,'']]], + ['classifier_20c_1',['SVM Classifier C++',['../index.html',1,'']]] +]; diff --git a/search/pages_1.js b/search/pages_1.js new file mode 100644 index 0000000..f90218c --- /dev/null +++ b/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['svm_20classifier_20c_0',['SVM Classifier C++',['../index.html',1,'']]] +]; diff --git a/search/search.css b/search/search.css new file mode 100644 index 0000000..19f76f9 --- /dev/null +++ b/search/search.css @@ -0,0 +1,291 @@ +/*---------------- Search Box positioning */ + +#main-menu > li:last-child { + /* This
  • object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} + +#MSearchBox { + display: inline-block; + white-space : nowrap; + background: var(--search-background-color); + border-radius: 0.65em; + box-shadow: var(--search-box-shadow); + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; +} + + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: var(--search-foreground-color); + outline: none; + font-family: var(--font-family-search); + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: var(--search-active-color); +} + + + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt var(--font-family-search); + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: var(--font-family-monospace); + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: var(--search-filter-foreground-color); + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: var(--search-filter-foreground-color); + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); + z-index:10000; + width: 300px; + height: 400px; + overflow: auto; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +div.SRPage { + margin: 5px 2px; + background-color: var(--search-results-background-color); +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: var(--font-family-search); +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: var(--font-family-search); +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: var(--nav-gradient-active-image-parent); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/search/search.js b/search/search.js new file mode 100644 index 0000000..6fd40c6 --- /dev/null +++ b/search/search.js @@ -0,0 +1,840 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + e.stopPropagation(); + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var jsFile; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); + } + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + if (idx!=-1) { + searchResults.Search(searchValue); + } else { // no file with search results => force empty search results + searchResults.Search('===='); + } + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); + } + + this.lastSearchValue = searchValue; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + this.searchActive = true; + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + this.DOMSearchField().value = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults(resultsPath) +{ + var results = document.getElementById("SRResults"); + results.innerHTML = ''; + for (var e=0; e + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    svm_classifier::EvaluationMetrics Member List
    +
    + + + + + diff --git a/structsvm__classifier_1_1EvaluationMetrics.html b/structsvm__classifier_1_1EvaluationMetrics.html new file mode 100644 index 0000000..da7e250 --- /dev/null +++ b/structsvm__classifier_1_1EvaluationMetrics.html @@ -0,0 +1,211 @@ + + + + + + + +SVM Classifier C++: svm_classifier::EvaluationMetrics Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    + +
    svm_classifier::EvaluationMetrics Struct Reference
    +
    +
    + +

    Model evaluation metrics. + More...

    + +

    #include <types.hpp>

    + + + + + + + + + + + + + + + + + +

    +Public Attributes

    double accuracy = 0.0
     Classification accuracy.
     
    double precision = 0.0
     Macro-averaged precision.
     
    double recall = 0.0
     Macro-averaged recall.
     
    double f1_score = 0.0
     Macro-averaged F1-score.
     
    std::vector< std::vector< int > > confusion_matrix
     Confusion matrix.
     
    +

    Detailed Description

    +

    Model evaluation metrics.

    + +

    Definition at line 70 of file types.hpp.

    +

    Member Data Documentation

    + +

    ◆ accuracy

    + +
    +
    + + + + +
    double svm_classifier::EvaluationMetrics::accuracy = 0.0
    +
    + +

    Classification accuracy.

    + +

    Definition at line 71 of file types.hpp.

    + +
    +
    + +

    ◆ confusion_matrix

    + +
    +
    + + + + +
    std::vector<std::vector<int> > svm_classifier::EvaluationMetrics::confusion_matrix
    +
    + +

    Confusion matrix.

    + +

    Definition at line 75 of file types.hpp.

    + +
    +
    + +

    ◆ f1_score

    + +
    +
    + + + + +
    double svm_classifier::EvaluationMetrics::f1_score = 0.0
    +
    + +

    Macro-averaged F1-score.

    + +

    Definition at line 74 of file types.hpp.

    + +
    +
    + +

    ◆ precision

    + +
    +
    + + + + +
    double svm_classifier::EvaluationMetrics::precision = 0.0
    +
    + +

    Macro-averaged precision.

    + +

    Definition at line 72 of file types.hpp.

    + +
    +
    + +

    ◆ recall

    + +
    +
    + + + + +
    double svm_classifier::EvaluationMetrics::recall = 0.0
    +
    + +

    Macro-averaged recall.

    + +

    Definition at line 73 of file types.hpp.

    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/structsvm__classifier_1_1PredictionResult-members.html b/structsvm__classifier_1_1PredictionResult-members.html new file mode 100644 index 0000000..a9c197a --- /dev/null +++ b/structsvm__classifier_1_1PredictionResult-members.html @@ -0,0 +1,93 @@ + + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    svm_classifier::PredictionResult Member List
    +
    + + + + + diff --git a/structsvm__classifier_1_1PredictionResult.html b/structsvm__classifier_1_1PredictionResult.html new file mode 100644 index 0000000..449eae6 --- /dev/null +++ b/structsvm__classifier_1_1PredictionResult.html @@ -0,0 +1,190 @@ + + + + + + + +SVM Classifier C++: svm_classifier::PredictionResult Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    + +
    svm_classifier::PredictionResult Struct Reference
    +
    +
    + +

    Prediction result structure. + More...

    + +

    #include <types.hpp>

    + + + + + + + + + + + + + + +

    +Public Attributes

    std::vector< int > predictions
     Predicted class labels.
     
    std::vector< std::vector< double > > probabilities
     Class probabilities (if available)
     
    std::vector< std::vector< double > > decision_values
     Decision function values.
     
    bool has_probabilities = false
     Whether probabilities are available.
     
    +

    Detailed Description

    +

    Prediction result structure.

    + +

    Definition at line 49 of file types.hpp.

    +

    Member Data Documentation

    + +

    ◆ decision_values

    + +
    +
    + + + + +
    std::vector<std::vector<double> > svm_classifier::PredictionResult::decision_values
    +
    + +

    Decision function values.

    + +

    Definition at line 52 of file types.hpp.

    + +
    +
    + +

    ◆ has_probabilities

    + +
    +
    + + + + +
    bool svm_classifier::PredictionResult::has_probabilities = false
    +
    + +

    Whether probabilities are available.

    + +

    Definition at line 53 of file types.hpp.

    + +
    +
    + +

    ◆ predictions

    + +
    +
    + + + + +
    std::vector<int> svm_classifier::PredictionResult::predictions
    +
    + +

    Predicted class labels.

    + +

    Definition at line 50 of file types.hpp.

    + +
    +
    + +

    ◆ probabilities

    + +
    +
    + + + + +
    std::vector<std::vector<double> > svm_classifier::PredictionResult::probabilities
    +
    + +

    Class probabilities (if available)

    + +

    Definition at line 51 of file types.hpp.

    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/structsvm__classifier_1_1TrainingMetrics-members.html b/structsvm__classifier_1_1TrainingMetrics-members.html new file mode 100644 index 0000000..45198e7 --- /dev/null +++ b/structsvm__classifier_1_1TrainingMetrics-members.html @@ -0,0 +1,94 @@ + + + + + + + +SVM Classifier C++: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    svm_classifier::TrainingMetrics Member List
    +
    + + + + + diff --git a/structsvm__classifier_1_1TrainingMetrics.html b/structsvm__classifier_1_1TrainingMetrics.html new file mode 100644 index 0000000..b29546e --- /dev/null +++ b/structsvm__classifier_1_1TrainingMetrics.html @@ -0,0 +1,208 @@ + + + + + + + +SVM Classifier C++: svm_classifier::TrainingMetrics Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    + +
    svm_classifier::TrainingMetrics Struct Reference
    +
    +
    + +

    Training metrics structure. + More...

    + +

    #include <types.hpp>

    + + + + + + + + + + + + + + + + +

    +Public Attributes

    double training_time = 0.0
     Training time in seconds.
     
    int support_vectors = 0
     Number of support vectors.
     
    int iterations = 0
     Number of iterations.
     
    double objective_value = 0.0
     Final objective value.
     
    TrainingStatus status = TrainingStatus::SUCCESS
     
    +

    Detailed Description

    +

    Training metrics structure.

    + +

    Definition at line 59 of file types.hpp.

    +

    Member Data Documentation

    + +

    ◆ iterations

    + +
    +
    + + + + +
    int svm_classifier::TrainingMetrics::iterations = 0
    +
    + +

    Number of iterations.

    + +

    Definition at line 62 of file types.hpp.

    + +
    +
    + +

    ◆ objective_value

    + +
    +
    + + + + +
    double svm_classifier::TrainingMetrics::objective_value = 0.0
    +
    + +

    Final objective value.

    + +

    Definition at line 63 of file types.hpp.

    + +
    +
    + +

    ◆ status

    + +
    +
    + + + + +
    TrainingStatus svm_classifier::TrainingMetrics::status = TrainingStatus::SUCCESS
    +
    + +

    Definition at line 64 of file types.hpp.

    + +
    +
    + +

    ◆ support_vectors

    + +
    +
    + + + + +
    int svm_classifier::TrainingMetrics::support_vectors = 0
    +
    + +

    Number of support vectors.

    + +

    Definition at line 61 of file types.hpp.

    + +
    +
    + +

    ◆ training_time

    + +
    +
    + + + + +
    double svm_classifier::TrainingMetrics::training_time = 0.0
    +
    + +

    Training time in seconds.

    + +

    Definition at line 60 of file types.hpp.

    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/svm__classifier_8hpp_source.html b/svm__classifier_8hpp_source.html new file mode 100644 index 0000000..7fdeec4 --- /dev/null +++ b/svm__classifier_8hpp_source.html @@ -0,0 +1,238 @@ + + + + + + + +SVM Classifier C++: include/svm_classifier/svm_classifier.hpp Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    svm_classifier.hpp
    +
    +
    +
    1#pragma once
    +
    2
    +
    3#include "types.hpp"
    +
    4#include "kernel_parameters.hpp"
    +
    5#include "data_converter.hpp"
    +
    6#include "multiclass_strategy.hpp"
    +
    7#include <torch/torch.h>
    +
    8#include <nlohmann/json.hpp>
    +
    9#include <memory>
    +
    10#include <string>
    +
    11
    +
    12namespace svm_classifier {
    +
    13
    +
    + +
    22 public:
    + +
    27
    +
    32 explicit SVMClassifier(const nlohmann::json& config);
    +
    33
    +
    40 SVMClassifier(KernelType kernel,
    +
    41 double C = 1.0,
    +
    42 MulticlassStrategy multiclass_strategy = MulticlassStrategy::ONE_VS_REST);
    +
    43
    + +
    48
    +
    52 SVMClassifier(const SVMClassifier&) = delete;
    +
    53
    + +
    58
    + +
    63
    +
    67 SVMClassifier& operator=(SVMClassifier&&) noexcept;
    +
    68
    +
    77 TrainingMetrics fit(const torch::Tensor& X, const torch::Tensor& y);
    +
    78
    +
    85 torch::Tensor predict(const torch::Tensor& X);
    +
    86
    +
    93 torch::Tensor predict_proba(const torch::Tensor& X);
    +
    94
    +
    101 torch::Tensor decision_function(const torch::Tensor& X);
    +
    102
    +
    110 double score(const torch::Tensor& X, const torch::Tensor& y_true);
    +
    111
    +
    118 EvaluationMetrics evaluate(const torch::Tensor& X, const torch::Tensor& y_true);
    +
    119
    +
    125 void set_parameters(const nlohmann::json& config);
    +
    126
    +
    131 nlohmann::json get_parameters() const;
    +
    132
    +
    137 bool is_fitted() const { return is_fitted_; }
    +
    138
    +
    143 int get_n_classes() const;
    +
    144
    +
    149 std::vector<int> get_classes() const;
    +
    150
    +
    155 int get_n_features() const { return n_features_; }
    +
    156
    +
    161 TrainingMetrics get_training_metrics() const { return training_metrics_; }
    +
    162
    + +
    168
    +
    174 void save_model(const std::string& filename) const;
    +
    175
    +
    181 void load_model(const std::string& filename);
    +
    182
    +
    187 KernelType get_kernel_type() const { return params_.get_kernel_type(); }
    +
    188
    +
    193 MulticlassStrategy get_multiclass_strategy() const { return params_.get_multiclass_strategy(); }
    +
    194
    +
    199 SVMLibrary get_svm_library() const { return get_svm_library(params_.get_kernel_type()); }
    +
    200
    +
    208 std::vector<double> cross_validate(const torch::Tensor& X,
    +
    209 const torch::Tensor& y,
    +
    210 int cv = 5);
    +
    211
    +
    220 nlohmann::json grid_search(const torch::Tensor& X,
    +
    221 const torch::Tensor& y,
    +
    222 const nlohmann::json& param_grid,
    +
    223 int cv = 5);
    +
    224
    +
    230 torch::Tensor get_feature_importance() const;
    +
    231
    +
    235 void reset();
    +
    236
    +
    237 private:
    +
    238 KernelParameters params_;
    +
    239 std::unique_ptr<MulticlassStrategyBase> multiclass_strategy_;
    +
    240 std::unique_ptr<DataConverter> data_converter_;
    +
    241
    +
    242 bool is_fitted_;
    +
    243 int n_features_;
    +
    244 TrainingMetrics training_metrics_;
    +
    245
    +
    252 void validate_input(const torch::Tensor& X,
    +
    253 const torch::Tensor& y = torch::Tensor(),
    +
    254 bool check_fitted = false);
    +
    255
    +
    259 void initialize_multiclass_strategy();
    +
    260
    +
    267 std::vector<std::vector<int>> calculate_confusion_matrix(const std::vector<int>& y_true,
    +
    268 const std::vector<int>& y_pred);
    +
    269
    +
    275 std::tuple<double, double, double> calculate_metrics_from_confusion_matrix(
    +
    276 const std::vector<std::vector<int>>& confusion_matrix);
    +
    277
    +
    286 std::tuple<torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor>
    +
    287 split_for_cv(const torch::Tensor& X, const torch::Tensor& y, int fold, int n_folds);
    +
    288
    +
    294 std::vector<nlohmann::json> generate_param_combinations(const nlohmann::json& param_grid);
    +
    295 };
    +
    +
    296
    +
    297} // namespace svm_classifier
    +
    Support Vector Machine Classifier with scikit-learn compatible API.
    +
    double score(const torch::Tensor &X, const torch::Tensor &y_true)
    Calculate accuracy score on test data.
    +
    TrainingMetrics get_training_metrics() const
    Get training metrics from last fit.
    +
    MulticlassStrategy get_multiclass_strategy() const
    Get multiclass strategy.
    +
    SVMClassifier & operator=(const SVMClassifier &)=delete
    Copy assignment (deleted - models are not copyable)
    + +
    torch::Tensor get_feature_importance() const
    Get feature importance (for linear kernels only)
    +
    SVMClassifier(const nlohmann::json &config)
    Constructor with JSON parameters.
    +
    SVMClassifier(const SVMClassifier &)=delete
    Copy constructor (deleted - models are not copyable)
    +
    SVMLibrary get_svm_library() const
    Get SVM library being used.
    +
    EvaluationMetrics evaluate(const torch::Tensor &X, const torch::Tensor &y_true)
    Calculate detailed evaluation metrics.
    +
    SVMClassifier()
    Default constructor with default parameters.
    +
    bool supports_probability() const
    Check if the current model supports probability prediction.
    +
    std::vector< double > cross_validate(const torch::Tensor &X, const torch::Tensor &y, int cv=5)
    Perform cross-validation.
    +
    KernelType get_kernel_type() const
    Get kernel type.
    +
    void load_model(const std::string &filename)
    Load model from file.
    +
    torch::Tensor predict(const torch::Tensor &X)
    Predict class labels for samples.
    +
    bool is_fitted() const
    Check if the model is fitted/trained.
    +
    int get_n_classes() const
    Get the number of classes.
    +
    int get_n_features() const
    Get the number of features.
    +
    nlohmann::json get_parameters() const
    Get current parameters as JSON.
    +
    TrainingMetrics fit(const torch::Tensor &X, const torch::Tensor &y)
    Train the SVM classifier.
    +
    SVMClassifier(KernelType kernel, double C=1.0, MulticlassStrategy multiclass_strategy=MulticlassStrategy::ONE_VS_REST)
    Constructor with explicit parameters.
    +
    void reset()
    Reset the classifier (clear trained model)
    +
    torch::Tensor predict_proba(const torch::Tensor &X)
    Predict class probabilities for samples.
    +
    void save_model(const std::string &filename) const
    Save model to file.
    +
    torch::Tensor decision_function(const torch::Tensor &X)
    Get decision function values.
    +
    void set_parameters(const nlohmann::json &config)
    Set parameters from JSON configuration.
    +
    SVMClassifier(SVMClassifier &&) noexcept
    Move constructor.
    +
    std::vector< int > get_classes() const
    Get unique class labels.
    +
    nlohmann::json grid_search(const torch::Tensor &X, const torch::Tensor &y, const nlohmann::json &param_grid, int cv=5)
    Find optimal hyperparameters using grid search.
    +
    Model evaluation metrics.
    Definition types.hpp:70
    +
    Training metrics structure.
    Definition types.hpp:59
    +
    + + + + diff --git a/sync_off.png b/sync_off.png new file mode 100644 index 0000000..3b443fc Binary files /dev/null and b/sync_off.png differ diff --git a/sync_on.png b/sync_on.png new file mode 100644 index 0000000..e08320f Binary files /dev/null and b/sync_on.png differ diff --git a/tab_a.png b/tab_a.png new file mode 100644 index 0000000..3b725c4 Binary files /dev/null and b/tab_a.png differ diff --git a/tab_ad.png b/tab_ad.png new file mode 100644 index 0000000..e34850a Binary files /dev/null and b/tab_ad.png differ diff --git a/tab_b.png b/tab_b.png new file mode 100644 index 0000000..e2b4a86 Binary files /dev/null and b/tab_b.png differ diff --git a/tab_bd.png b/tab_bd.png new file mode 100644 index 0000000..91c2524 Binary files /dev/null and b/tab_bd.png differ diff --git a/tab_h.png b/tab_h.png new file mode 100644 index 0000000..fd5cb70 Binary files /dev/null and b/tab_h.png differ diff --git a/tab_hd.png b/tab_hd.png new file mode 100644 index 0000000..2489273 Binary files /dev/null and b/tab_hd.png differ diff --git a/tab_s.png b/tab_s.png new file mode 100644 index 0000000..ab478c9 Binary files /dev/null and b/tab_s.png differ diff --git a/tab_sd.png b/tab_sd.png new file mode 100644 index 0000000..757a565 Binary files /dev/null and b/tab_sd.png differ diff --git a/tabs.css b/tabs.css new file mode 100644 index 0000000..df7944b --- /dev/null +++ b/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all 0.25s;transition:all 0.25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked~.main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked~.main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked~.main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}#main-menu-state:not(:checked)~#main-menu{display:none}#main-menu-state:checked~#main-menu{display:block}@media (min-width: 768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked)~#main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:none}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} diff --git a/types_8hpp_source.html b/types_8hpp_source.html new file mode 100644 index 0000000..48386a7 --- /dev/null +++ b/types_8hpp_source.html @@ -0,0 +1,215 @@ + + + + + + + +SVM Classifier C++: include/svm_classifier/types.hpp Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    SVM Classifier C++ 1.0.0 +
    +
    High-performance Support Vector Machine classifier with scikit-learn compatible API
    +
    +
    + + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    types.hpp
    +
    +
    +
    1#pragma once
    +
    2
    +
    3#include <string>
    +
    4#include <vector>
    +
    5#include <memory>
    +
    6
    +
    7namespace svm_classifier {
    +
    8
    +
    12 enum class KernelType {
    +
    13 LINEAR,
    +
    14 RBF,
    +
    15 POLYNOMIAL,
    +
    16 SIGMOID
    +
    17 };
    +
    18
    +
    22 enum class MulticlassStrategy {
    +
    23 ONE_VS_REST,
    +
    24 ONE_VS_ONE
    +
    25 };
    +
    26
    +
    30 enum class SVMLibrary {
    +
    31 LIBLINEAR,
    +
    32 LIBSVM
    +
    33 };
    +
    34
    +
    38 enum class TrainingStatus {
    +
    39 SUCCESS,
    +
    40 INVALID_PARAMETERS,
    +
    41 INSUFFICIENT_DATA,
    +
    42 MEMORY_ERROR,
    +
    43 CONVERGENCE_ERROR
    +
    44 };
    +
    45
    +
    + +
    50 std::vector<int> predictions;
    +
    51 std::vector<std::vector<double>> probabilities;
    +
    52 std::vector<std::vector<double>> decision_values;
    +
    53 bool has_probabilities = false;
    +
    54 };
    +
    +
    55
    +
    + +
    60 double training_time = 0.0;
    + +
    62 int iterations = 0;
    +
    63 double objective_value = 0.0;
    +
    64 TrainingStatus status = TrainingStatus::SUCCESS;
    +
    65 };
    +
    +
    66
    +
    + +
    71 double accuracy = 0.0;
    +
    72 double precision = 0.0;
    +
    73 double recall = 0.0;
    +
    74 double f1_score = 0.0;
    +
    75 std::vector<std::vector<int>> confusion_matrix;
    +
    76 };
    +
    +
    77
    +
    81 inline std::string kernel_type_to_string(KernelType kernel)
    +
    82 {
    +
    83 switch (kernel) {
    +
    84 case KernelType::LINEAR: return "linear";
    +
    85 case KernelType::RBF: return "rbf";
    +
    86 case KernelType::POLYNOMIAL: return "polynomial";
    +
    87 case KernelType::SIGMOID: return "sigmoid";
    +
    88 default: return "unknown";
    +
    89 }
    +
    90 }
    +
    91
    +
    95 inline KernelType string_to_kernel_type(const std::string& kernel_str)
    +
    96 {
    +
    97 if (kernel_str == "linear") return KernelType::LINEAR;
    +
    98 if (kernel_str == "rbf") return KernelType::RBF;
    +
    99 if (kernel_str == "polynomial" || kernel_str == "poly") return KernelType::POLYNOMIAL;
    +
    100 if (kernel_str == "sigmoid") return KernelType::SIGMOID;
    +
    101 throw std::invalid_argument("Unknown kernel type: " + kernel_str);
    +
    102 }
    +
    103
    +
    107 inline std::string multiclass_strategy_to_string(MulticlassStrategy strategy)
    +
    108 {
    +
    109 switch (strategy) {
    +
    110 case MulticlassStrategy::ONE_VS_REST: return "ovr";
    +
    111 case MulticlassStrategy::ONE_VS_ONE: return "ovo";
    +
    112 default: return "unknown";
    +
    113 }
    +
    114 }
    +
    115
    +
    119 inline MulticlassStrategy string_to_multiclass_strategy(const std::string& strategy_str)
    +
    120 {
    +
    121 if (strategy_str == "ovr" || strategy_str == "one_vs_rest") {
    +
    122 return MulticlassStrategy::ONE_VS_REST;
    +
    123 }
    +
    124 if (strategy_str == "ovo" || strategy_str == "one_vs_one") {
    +
    125 return MulticlassStrategy::ONE_VS_ONE;
    +
    126 }
    +
    127 throw std::invalid_argument("Unknown multiclass strategy: " + strategy_str);
    +
    128 }
    +
    129
    +
    133 inline SVMLibrary get_svm_library(KernelType kernel)
    +
    134 {
    +
    135 return (kernel == KernelType::LINEAR) ? SVMLibrary::LIBLINEAR : SVMLibrary::LIBSVM;
    +
    136 }
    +
    137
    +
    138} // namespace svm_classifier
    +
    Model evaluation metrics.
    Definition types.hpp:70
    +
    double f1_score
    Macro-averaged F1-score.
    Definition types.hpp:74
    +
    double recall
    Macro-averaged recall.
    Definition types.hpp:73
    +
    std::vector< std::vector< int > > confusion_matrix
    Confusion matrix.
    Definition types.hpp:75
    +
    double accuracy
    Classification accuracy.
    Definition types.hpp:71
    +
    double precision
    Macro-averaged precision.
    Definition types.hpp:72
    +
    Prediction result structure.
    Definition types.hpp:49
    +
    std::vector< int > predictions
    Predicted class labels.
    Definition types.hpp:50
    +
    std::vector< std::vector< double > > decision_values
    Decision function values.
    Definition types.hpp:52
    +
    std::vector< std::vector< double > > probabilities
    Class probabilities (if available)
    Definition types.hpp:51
    +
    bool has_probabilities
    Whether probabilities are available.
    Definition types.hpp:53
    +
    Training metrics structure.
    Definition types.hpp:59
    +
    double objective_value
    Final objective value.
    Definition types.hpp:63
    +
    int support_vectors
    Number of support vectors.
    Definition types.hpp:61
    +
    int iterations
    Number of iterations.
    Definition types.hpp:62
    +
    double training_time
    Training time in seconds.
    Definition types.hpp:60
    +
    + + + +