===================================
HingeRampFD Component Specification
===================================

.. contents:: Contents
    :local:

Overview
========
**HingeRampFD component** is a feature descriptor.
This component produces an output by linear function with upper/lower limit.
The scale of the input must be INTEGER or REAL.

**Example**:

* SPD:

  .. code-block:: python

    dl1 -> hr1

    ---

    components:
        dl1:
            component: DataLoader

        hr1:
            component: HingeRampFDComponent
            features: scale == 'real' or scale == 'integer'
            hinge_ramp_param: [["re_match('.*Length', name)",
                                [{'slope': 2.0, 'intercept': 1.0,
                                  'upper_limit': 50.0, 'lower_limit': 0.0}]]]

* Input of the component:

 +--------+--------------+--------------+
 |   _sid | Sepal.Length | Petal.Length |
 +========+==============+==============+
 |   0    | 5.1          | 1.4          |
 +--------+--------------+--------------+
 |   1    | inf          | 1.4          |
 +--------+--------------+--------------+
 |   2    | 4.7          | 1.3          |
 +--------+--------------+--------------+
 |   3    | 4.6          | -inf         |
 +--------+--------------+--------------+
 |   4    | NaN          | NaN          |
 +--------+--------------+--------------+

* Output of the component:

 +--------+------------------------------------+------------------------------------+
 |   _sid | hr1(2.0:1.0:50.0:0.0)_Sepal.Length | hr1(2.0:1.0:50.0:0.0)_Petal.Length |
 +========+====================================+====================================+
 |   0    | 11.2                               | 3.8                                |
 +--------+------------------------------------+------------------------------------+
 |   1    | 50.0                               | 3.8                                |
 +--------+------------------------------------+------------------------------------+
 |   2    | 10.4                               | 3.6                                |
 +--------+------------------------------------+------------------------------------+
 |   3    | 10.2                               | 0.0                                |
 +--------+------------------------------------+------------------------------------+
 |   4    | NaN                                | NaN                                |
 +--------+------------------------------------+------------------------------------+

This component has no component-specific external formats.

.. seealso::

    Component-common external format files in :ref:`convert_process`

|

Parameters
==========
Here are the component-specific parameters for the **HingeRampFD component**.

SPD
---

The following parameter is for "components" section of SPD.

.. list-table::
   :header-rows: 1
   :widths: 1, 25, 1, 1, 25

   * - Parameter Name
     - Type
     - Domain
     - Default Value
     - Description
   * - hinge_ramp_param [1]_
     - [[**feature_expr**, [{**params**}]]]
     - --
     - --
     - Specifies target features and parameters of HingeRamp function.

.. [1] Required parameter

Details of hinge_ramp_param
---------------------------

* **feature_expr** follows the format described in *Attribute Selection* of *SPD (SAMPO Process Description) File Specification*::

      're_match(".*Length", name)'

* **params** can be described as dict::

      {'slope':2.0, 'intercept':1.0, 'upper_limit':50.0, 'lower_limit':0.0}

  Here we define the relationship of an input :math:`x` and an output :math:`y` through the linear function :math:`y = ax + b`.

 .. list-table::
    :header-rows: 1
    :widths: 15, 5, 15, 10, 30

    * - Key of params
      - Type
      - Domain
      - Default Value
      - Description
    * - slope
      - float
      - (-inf, 0), (0, inf)
      - 1.0
      - :math:`a` in the linear function :math:`y = ax + b`.
    * - intercept
      - float
      - (-inf, inf)
      - 0.0
      - :math:`b` in the linear function :math:`y = ax + b`.
    * - upper_limit
      - float
      - (-inf, inf]
      - inf
      - The upper limit of the output :math:`y`.
    * - lower_limit
      - float
      - [-inf, inf)
      - -inf
      - The lower limit of the output :math:`y`.

 ``upper_limit`` must be larger than ``lower_limit``.

|

Utilizable Sample Metadata
==========================
There are no component-specific sample metadata available.

|

Output Attributes
=================
**HingeRampFD component** generates the following attribute:

.. list-table::
  :header-rows: 1
  :widths: 3,1,3

  * - Attribute Name
    - Scale
    - Description
  * - *<component_id>*\ (<slope>:<intercept>:<upper_limit>:<lower_limit>)\ _\ *<original_attribute_name>*
    - REAL
    - Linearly-transformed value with upper/lower limit of the original value.

These attributes are in the component output data. These can be loaded
in SAMPO API or saved as data.csv after executing :ref:`convert_process`.

.. seealso::

    Obtaining process results via `ProcessResultLoader <../../api/process_result_loader.html>`_.

|

Attribute Metadata
==================
The metadata of the output attributes is created with the following rules.

Context Rule
------------
.. list-table::
  :header-rows: 1
  :widths: 3,1,3

  * - Attribute Name
    - Context Name
    - Description
  * - *<component_id>*\ (<slope>:<intercept>:<upper_limit>:<lower_limit>)\ _\ *<original_attribute_name>*
    - slope
    - Set the value of ``slope``.
  * - *<component_id>*\ (<slope>:<intercept>:<upper_limit>:<lower_limit>)\ _\ *<original_attribute_name>*
    - intercept
    - Set the value of ``intercept``.
  * - *<component_id>*\ (<slope>:<intercept>:<upper_limit>:<lower_limit>)\ _\ *<original_attribute_name>*
    - upper_limit
    - Set the value of ``upper_limit``.
  * - *<component_id>*\ (<slope>:<intercept>:<upper_limit>:<lower_limit>)\ _\ *<original_attribute_name>*
    - lower_limit
    - Set the value of ``lower_limit``.

Derivation Rule
---------------
Each new attribute is derived from the corresponding attribute selected by the ``features`` parameter of the component.

Example
-------
.. code-block:: javascript

    {
        "nodes": [
            {"aid": "_sid", "name": "_sid", ... },
            {"aid": "dl1[0]", "name": "Sepal.Length", ... },
            {"aid": "dl1[1]", "name": "Petal.Length", ... },
            {"aid": "hr1[0]", "name": "hr1(2.0:1.0:50.0:0.0)_Sepal.Length", "scale": "real",
             "is_excluded": false, "cid": "hr1", "cindex": 0, "values": null, "is_kept": false,
             "context": {"slope": 2.0000000000000000e+00, "intercept": 1.0000000000000000e+00,
                         "lower_limit": 0.0000000000000000e+00, "upper_limit": 5.0000000000000000e+01}},
            {"aid": "hr1[1]", "name": "hr1(2.0:1.0:50.0:0.0)_Petal.Length", "scale": "real",
             "is_excluded": false,"cid": "hr1", "cindex": 1, "values": null, "is_kept": false,
             "context": {"slope": 2.0000000000000000e+00, "intercept": 1.0000000000000000e+00,
                         "lower_limit": 0.0000000000000000e+00, "upper_limit": 5.0000000000000000e+01}}
        ],
        "links": [
            {"source": "dl1[0]", "target": "hr1[0]"},
            {"source": "dl1[1]", "target": "hr1[1]"}
        ]
    }

.. seealso::

    Attribute metadata file format in :ref:`Attribute Metadata File Specification <attribute-metadata>`

|

Model
=====
The model of this component can be described by its fd_params.

.. list-table::
  :header-rows: 1
  :widths: 3,1,3

  * - fd_params
    - Type
    - Description
  * - source_attr_names
    - list of string
    - A list of attribute names where the output attribute is derived from.
  * - params
    - dict
    - The keys of this dictionary are the same as the context of this component's Attribute Metadata.

When loaded in the SAMPO API, the model is represented as a dict of its fd_params.

.. seealso::

    Obtaining process results via `ProcessResultLoader <../../api/process_result_loader.html>`_.

::

    {'fd_params':
        [{'source_attr_names': ['Sepal.Length'],
          'params': {'slope': 2.0000000000000000e+00,
                     'intercept': 1.0000000000000000e+00,
                     'lower_limit': 0.0000000000000000e+00,
                     'upper_limit': 5.0000000000000000e+01}},
         {'source_attr_names': ['Petal.Length'],
          'params': {'slope': 2.0000000000000000e+00,
                     'intercept': 1.0000000000000000e+00,
                     'lower_limit': 0.0000000000000000e+00,
                     'upper_limit': 5.0000000000000000e+01}}]}


Details
=======
* In the running phase, the output values are calculated by the input values and parameter of linear function as follows.

  * Linear Function

    :math:`y =` ``slope`` :math:`\times` **input value** :math:`+` ``intercept``

  * Conditional Branching

    :math:`y <` ``lower_limit``:
      **output value** = ``lower_limit``

    ``lower_limit`` :math:`\leq y \leq` ``upper_limit``:
      **output value** = :math:`y`

    ``upper_limit`` :math:`< y`:
      **output value** = ``upper_limit``

  where ``slope``, ``intercept``, ``lower_limit``, and ``upper_limit`` are the component parameters.
