[prev in list] [next in list] [prev in thread] [next in thread] 

List:       insight-users
Subject:    Re: [ITK-users] VariableLengthVector and multiplication
From:       DÅ <dzenanz () gmail ! com>
Date:       2017-11-24 13:46:05
Message-ID: CAPf2UMRCBxpWz9wY27o8K5h9GbB_o3Z_qyVQFY5jhegnLCcF_Q () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


That looks about right. Thanks for sharing your solution.

Regards,
Dženan

On Fri, Nov 24, 2017 at 6:54 AM, Cyril Mory <cyril.mory@creatis.insa-lyon.fr
> wrote:

> Thanks.
>
> Here is the solution I used, which works but may be sub-optimal:
>
> namespace Functor
> {
>   template< class TPixel, class TInternal>
>   class DotProduct
>   {
>   public:
>     DotProduct() {}
>     ~DotProduct() {}
>     bool operator!=(const DotProduct &) const
>     {
>       return false;
>     }
>
>     bool operator==(const DotProduct & other) const
>     {
>       return !( *this != other );
>     }
>
>   template<typename T = TPixel>
>   inline
>   typename itk::mpl::EnableIf<itk::mpl::IsSame<T, TInternal>,
> TInternal>::Type
>   operator()(const TInternal & A, const TInternal & B) const
>   { return static_cast<TInternal>( A * B ); }
>
>   template<typename T = TPixel>
>   typename itk::mpl::DisableIf<itk::mpl::IsSame<T, TInternal>,
> TInternal>::Type
>   operator()(const TPixel & A, const TPixel & B) const
>     {
>     TInternal out = 0;
>     for (unsigned int component=0; component < itk::NumericTraits<TPixel>::GetLength(A);
> component++)
>       {
>       out += A[component] * B[component];
>       }
>     return out;
>     }
>   };
> } // end namespace functor
>
>
> On 22/11/2017 18:42, Dženan Zukić wrote:
>
> I found it. Construct is called *EnableIf*, and you can see how it is
> used in *ITK\Modules\Core\Common\test\itkEnableIfTest.cxx*
>
> Regards
>
> On Wed, Nov 22, 2017 at 10:17 AM, Dženan Zukić <dzenanz@gmail.com> wrote:
>
>> Hi Cyril,
>>
>> Francois has recently used compileif construct. That might help you. But
>> I can't find an instance of it right now.
>>
>> Also, we are moving to discourse <https://discourse.itk.org/>. Please
>> post follow-ups there.
>>
>> Regards,
>> Dženan
>>
>> On Wed, Nov 22, 2017 at 9:54 AM, Cyril Mory <
>> cyril.mory@creatis.insa-lyon.fr> wrote:
>>
>>> Thanks for this answer.
>>>
>>> I am trying the approach you suggested, and would like to write a dot
>>> product functor that would work either on scalars (in which case it would
>>> perform a simple product) or on itk::VariableLengthVector of scalars (in
>>> which case it would perform a dot product).
>>>
>>> I found the "itk::NumericTraits<TPixel>::GetLength()" method, which
>>> works in both cases, and so I tried this:
>>>
>>>
>>> namespace Functor
>>> {
>>>   template< class TPixel, class TInternal>
>>>   class DotProduct
>>>   {
>>>   public:
>>>     DotProduct() {}
>>>     ~DotProduct() {}
>>>     bool operator!=(const DotProduct &) const
>>>     {
>>>       return false;
>>>     }
>>>
>>>     bool operator==(const DotProduct & other) const
>>>     {
>>>       return !( *this != other );
>>>     }
>>>
>>>     inline TInternal operator()(const TPixel & A, const TPixel & B) const
>>>     {
>>>     TInternal out = 0;
>>>     for (unsigned int component=0; component <
>>> itk::NumericTraits<TPixel>::GetLength(); component++)
>>>       {
>>>       out += A[component] * B[component];
>>>       }
>>>     return out;
>>>     }
>>>   };
>>> } // end namespace functor
>>>
>>>
>>> But it does not compile with itk::Image inputs, since the pixels A and B
>>> have no [ ] operator. Is there a standard way around this problem ?
>>>
>>> Regards,
>>> Cyril
>>>
>>>
>>> On 22/11/2017 14:38, Lowekamp, Bradley (NIH/NLM/LHC) [C] wrote:
>>>
>>>> Hello,
>>>>
>>>> There are an incredible number of different per-pixel operations that
>>>> could be implemented as ITK filters. We cannot provide them all. Many of
>>>> the basic operations are implemented as ITK filters these include
>>>> performing the basic C++ operators, such as +, -, * and /, on a per-pixel
>>>> basis.
>>>>
>>>> As you indicate there are many possible meanings for multiplication of
>>>> vector images, which can lead to confusion.
>>>>
>>>> ITK has a flexible set of Unary[1], Binary[2] functor filters. Classes
>>>> like the MultiplyImageFilter[3], are implemented by deriving from the base
>>>> functor classes. However it is easier to just use the base functor filter
>>>> and set the proper or custom functor, as in this example [4].
>>>>
>>>> It is fairly easy to write a functor for your specific purposes by
>>>> following the existing set [5]. It is common for filters to internally
>>>> define a private functor to perform one step in a large filter. Moving from
>>>> writing for loops on pixels to writing custom functors is part of good
>>>> usage of ITK.
>>>>
>>>>
>>>> Brad
>>>>
>>>>
>>>> [1] https://itk.org/Doxygen/html/classitk_1_1UnaryFunctorImageFi
>>>> lter.html
>>>> [2] https://itk.org/Doxygen/html/classitk_1_1BinaryFunctorImageF
>>>> ilter.html
>>>> [3] https://itk.org/Doxygen/html/classitk_1_1MultiplyImageFilter.html
>>>> [4] https://itk.org/Doxygen/html/WikiExamples_2ImageProcessing_2
>>>> BinaryFunctorImageFilter_8cxx-example.html#_a1
>>>>
>>>> On 11/22/17, 5:15 AM, "Cyril Mory" <cyril.mory@creatis.insa-lyon.fr>
>>>> wrote:
>>>>
>>>>      Dear ITK users,
>>>>           I am using itk::VectorImage in some of my code, which uses
>>>>      itk::VariableLengthVector as pixel type. And I am wondering why
>>>>      itk::VariableLengthVector has so little support for multiplication.
>>>>      Currently, the * operator only supports multiplication by a scalar.
>>>>           It probably isn't simple, but I would need three additional
>>>> kinds of
>>>>      multiplication:
>>>>           - dot product with another VariableLengthVector (that has the
>>>> same
>>>>      length, although it is probably a waste of time to perform the
>>>> check
>>>>      every time), returning a scalar
>>>>           - component-wise multiplication, returning a
>>>> VariableLengthVector of the
>>>>      same length
>>>>           - left or right multiplication with a matrix (possibly an
>>>>      itk::VariableSizeMatrix) that has the correct size, but I
>>>> understand
>>>>      that this is probably the most complex one, and since it only
>>>> occurs
>>>>      rarely in my code, I can handle it with conversions to vnl::vector
>>>> and
>>>>      vnl::matrix
>>>>           Are there constraints that prevent at least the dot product
>>>> and
>>>>      component-wise multiplication operators from being implemented ?
>>>> If not,
>>>>      then I'd be happy to give it a try. Since both differ only by the
>>>> return
>>>>      type, two different operators would have to be used (I guess). Do
>>>> you
>>>>      have suggestions (which one should use *, and what should be the
>>>> other
>>>>      operator) ? In itk::Vector and itk::CovariantVector, the *
>>>> operator is
>>>>      used for dot product.
>>>>           Regards,
>>>>           Cyril
>>>>                The ITK community is transitioning from this mailing
>>>> list to discourse.itk.org. Please join us there!
>>>>      ________________________________
>>>>      Powered by www.kitware.com
>>>>           Visit other Kitware open-source projects at
>>>>      http://www.kitware.com/opensource/opensource.html
>>>>           Kitware offers ITK Training Courses, for more information
>>>> visit:
>>>>      http://www.kitware.com/products/protraining.php
>>>>           Please keep messages on-topic and check the ITK FAQ at:
>>>>      http://www.itk.org/Wiki/ITK_FAQ
>>>>           Follow this link to subscribe/unsubscribe:
>>>>      http://public.kitware.com/mailman/listinfo/insight-users
>>>>
>>>>
>>>>
>>> The ITK community is transitioning from this mailing list to
>>> discourse.itk.org. Please join us there!
>>> ________________________________
>>> Powered by www.kitware.com
>>>
>>> Visit other Kitware open-source projects at
>>> http://www.kitware.com/opensource/opensource.html
>>>
>>> Kitware offers ITK Training Courses, for more information visit:
>>> http://www.kitware.com/products/protraining.php
>>>
>>> Please keep messages on-topic and check the ITK FAQ at:
>>> http://www.itk.org/Wiki/ITK_FAQ
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://public.kitware.com/mailman/listinfo/insight-users
>>>
>>
>>
>
>

[Attachment #5 (text/html)]

<div dir="ltr"><div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">That looks about right. Thanks \
for sharing your solution.</div><div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small"><br></div><div \
class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">Regards,</div><div \
class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">Dženan</div></div><div \
class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 24, 2017 at 6:54 AM, \
Cyril Mory <span dir="ltr">&lt;<a href="mailto:cyril.mory@creatis.insa-lyon.fr" \
target="_blank">cyril.mory@creatis.insa-lyon.fr</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex">  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <p>Thanks. <br>
    </p>
    <p>Here is the solution I used, which works but may be sub-optimal:
      <br>
    </p>
    <p><span class="">namespace Functor<br>
      {<br>
         template&lt; class TPixel, class TInternal&gt;<br>
         class DotProduct<br>
         {<br>
         public:<br>
             DotProduct() {}<br>
             ~DotProduct() {}<br>
             bool operator!=(const DotProduct &amp;) const<br>
             {<br>
                 return false;<br>
             }<br>
      <br>
             bool operator==(const DotProduct &amp; other) const<br>
             {<br>
                 return !( *this != other );<br>
             }<br>
      <br></span>
         template&lt;typename T = TPixel&gt;<br>
         inline<br>
         typename itk::mpl::EnableIf&lt;itk::mpl::<wbr>IsSame&lt;T,
      TInternal&gt;, TInternal&gt;::Type<br>
         operator()(const TInternal &amp; A, const TInternal &amp; B)
      const<br>
         { return static_cast&lt;TInternal&gt;( A * B ); }<br>
      <br>
         template&lt;typename T = TPixel&gt;<br>
         typename itk::mpl::DisableIf&lt;itk::mpl::<wbr>IsSame&lt;T,
      TInternal&gt;, TInternal&gt;::Type<span class=""><br>
         operator()(const TPixel &amp; A, const TPixel &amp; B) const<br>
             {<br>
             TInternal out = 0;<br></span>
             for (unsigned int component=0; component &lt;
      itk::NumericTraits&lt;TPixel&gt;::<wbr>GetLength(A); component++)<span \
class=""><br>  {<br>
                 out += A[component] * B[component];<br>
                 }<br>
             return out;<br>
             }<br>
         };<br>
      } // end namespace functor<br>
      <br>
    </span></p><div><div class="h5">
    <br>
    <div class="m_3180900321465923040moz-cite-prefix">On 22/11/2017 18:42, Dženan \
Zukić  wrote:<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">I found  it. Construct is \
                called  <b>EnableIf</b>, and you can see how
          it is used in \
                <i>ITK\Modules\Core\Common\test\<wbr>itkEnableIfTest.cxx</i></div>
        <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small"><br>  </div>
        <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">Regards</div>  </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Wed, Nov 22, 2017 at 10:17 AM,
          Dženan Zukić <span dir="ltr">&lt;<a href="mailto:dzenanz@gmail.com" \
target="_blank">dzenanz@gmail.com</a>&gt;</span>  wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px \
#ccc solid;padding-left:1ex">  <div dir="ltr">
              <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">Hi  Cyril,</div>
              <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small"><br>  </div>
              <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">Francois  has recently used \
                compileif construct. That might help
                you. But I can&#39;t find an instance of it right now.</div>
              <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small"><br>  </div>
              <div class="gmail_default" \
                style="font-family:verdana,sans-serif;font-size:small">Also,
                we are moving to <a href="https://discourse.itk.org/" \
target="_blank">discourse</a>.  Please post follow-ups there.</div>
              <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small"><br>  </div>
              <div class="gmail_default" \
                style="font-family:verdana,sans-serif;font-size:small">Regards,</div>
              <div class="gmail_default" \
style="font-family:verdana,sans-serif;font-size:small">Dženan</div>  </div>
            <div class="m_3180900321465923040HOEnZb">
              <div class="m_3180900321465923040h5">
                <div class="gmail_extra"><br>
                  <div class="gmail_quote">On Wed, Nov 22, 2017 at 9:54
                    AM, Cyril Mory <span dir="ltr">&lt;<a \
href="mailto:cyril.mory@creatis.insa-lyon.fr" \
target="_blank">cyril.mory@creatis.insa-lyon.<wbr>fr</a>&gt;</span>  wrote:<br>
                    <blockquote class="gmail_quote" style="margin:0 0 0 \
.8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks  for this answer.<br>
                      <br>
                      I am trying the approach you suggested, and would
                      like to write a dot product functor that would
                      work either on scalars (in which case it would
                      perform a simple product) or on
                      itk::VariableLengthVector of scalars (in which
                      case it would perform a dot product).<br>
                      <br>
                      I found the \
&quot;itk::NumericTraits&lt;TPixel&gt;::G<wbr>etLength()&quot;  method, which works \
in both cases, and so I tried  this:<br>
                      <br>
                      <br>
                      namespace Functor<br>
                      {<br>
                         template&lt; class TPixel, class TInternal&gt;<br>
                         class DotProduct<br>
                         {<br>
                         public:<br>
                             DotProduct() {}<br>
                             ~DotProduct() {}<br>
                             bool operator!=(const DotProduct &amp;) const<br>
                             {<br>
                                 return false;<br>
                             }<br>
                      <br>
                             bool operator==(const DotProduct &amp; other)
                      const<br>
                             {<br>
                                 return !( *this != other );<br>
                             }<br>
                      <br>
                             inline TInternal operator()(const TPixel &amp;
                      A, const TPixel &amp; B) const<br>
                             {<br>
                             TInternal out = 0;<br>
                             for (unsigned int component=0; component &lt;
                      itk::NumericTraits&lt;TPixel&gt;::Ge<wbr>tLength();
                      component++)<br>
                                 {<br>
                                 out += A[component] * B[component];<br>
                                 }<br>
                             return out;<br>
                             }<br>
                         };<br>
                      } // end namespace functor<br>
                      <br>
                      <br>
                      But it does not compile with itk::Image inputs,
                      since the pixels A and B have no [ ] operator. Is
                      there a standard way around this problem ?<br>
                      <br>
                      Regards,<br>
                      Cyril
                      <div class="m_3180900321465923040m_-4725059247121473243HOEnZb">
                        <div \
class="m_3180900321465923040m_-4725059247121473243h5"><br>  <br>
                          On 22/11/2017 14:38, Lowekamp, Bradley
                          (NIH/NLM/LHC) [C] wrote:<br>
                          <blockquote class="gmail_quote" style="margin:0 0 0 \
.8ex;border-left:1px #ccc solid;padding-left:1ex">  Hello,<br>
                            <br>
                            There are an incredible number of different
                            per-pixel operations that could be
                            implemented as ITK filters. We cannot
                            provide them all. Many of the basic
                            operations are implemented as ITK filters
                            these include performing the basic C++
                            operators, such as +, -, * and /, on a
                            per-pixel basis.<br>
                            <br>
                            As you indicate there are many possible
                            meanings for multiplication of vector
                            images, which can lead to confusion.<br>
                            <br>
                            ITK has a flexible set of Unary[1],
                            Binary[2] functor filters. Classes like the
                            MultiplyImageFilter[3], are implemented by
                            deriving from the base functor classes.
                            However it is easier to just use the base
                            functor filter and set the proper or custom
                            functor, as in this example [4].<br>
                            <br>
                            It is fairly easy to write a functor for
                            your specific purposes by following the
                            existing set [5]. It is common for filters
                            to internally define a private functor to
                            perform one step in a large filter. Moving
                            from writing for loops on pixels to writing
                            custom functors is part of good usage of
                            ITK.<br>
                            <br>
                            <br>
                            Brad<br>
                            <br>
                            <br>
                            [1] <a \
href="https://itk.org/Doxygen/html/classitk_1_1UnaryFunctorImageFilter.html" \
rel="noreferrer" target="_blank">https://itk.org/Doxygen/html/c<wbr>lassitk_1_1UnaryFunctorImageFi<wbr>lter.html</a><br>
  [2] <a href="https://itk.org/Doxygen/html/classitk_1_1BinaryFunctorImageFilter.html" \
rel="noreferrer" target="_blank">https://itk.org/Doxygen/html/c<wbr>lassitk_1_1BinaryFunctorImageF<wbr>ilter.html</a><br>
  [3] <a href="https://itk.org/Doxygen/html/classitk_1_1MultiplyImageFilter.html" \
rel="noreferrer" target="_blank">https://itk.org/Doxygen/html/c<wbr>lassitk_1_1MultiplyImageFilter<wbr>.html</a><br>
  [4] <a href="https://itk.org/Doxygen/html/WikiExamples_2ImageProcessing_2BinaryFunctorImageFilter_8cxx-example.html#_a1" \
rel="noreferrer" target="_blank">https://itk.org/Doxygen/html/W<wbr>ikiExamples_2ImageProcessing_2<wbr>BinaryFunctorImageFilter_8cxx-<wbr>example.html#_a1</a><br>
  <br>
                            On 11/22/17, 5:15 AM, &quot;Cyril Mory&quot; &lt;<a \
href="mailto:cyril.mory@creatis.insa-lyon.fr" \
target="_blank">cyril.mory@creatis.insa-lyon.<wbr>fr</a>&gt;  wrote:<br>
                            <br>
                                    Dear ITK users,<br>
                                           I am using itk::VectorImage in
                            some of my code, which uses<br>
                                    itk::VariableLengthVector as pixel
                            type. And I am wondering why<br>
                                    itk::VariableLengthVector has so little
                            support for multiplication.<br>
                                    Currently, the * operator only supports
                            multiplication by a scalar.<br>
                                           It probably isn&#39;t simple, but I
                            would need three additional kinds of<br>
                                    multiplication:<br>
                                           - dot product with another
                            VariableLengthVector (that has the same<br>
                                    length, although it is probably a waste
                            of time to perform the check<br>
                                    every time), returning a scalar<br>
                                           - component-wise multiplication,
                            returning a VariableLengthVector of the<br>
                                    same length<br>
                                           - left or right multiplication
                            with a matrix (possibly an<br>
                                    itk::VariableSizeMatrix) that has the
                            correct size, but I understand<br>
                                    that this is probably the most complex
                            one, and since it only occurs<br>
                                    rarely in my code, I can handle it with
                            conversions to vnl::vector and<br>
                                    vnl::matrix<br>
                                           Are there constraints that prevent
                            at least the dot product and<br>
                                    component-wise multiplication operators
                            from being implemented ? If not,<br>
                                    then I&#39;d be happy to give it a try.
                            Since both differ only by the return<br>
                                    type, two different operators would
                            have to be used (I guess). Do you<br>
                                    have suggestions (which one should use
                            *, and what should be the other<br>
                                    operator) ? In itk::Vector and
                            itk::CovariantVector, the * operator is<br>
                                    used for dot product.<br>
                                           Regards,<br>
                                           Cyril<br>
                                                   The ITK community is
                            transitioning from this mailing list to <a \
href="http://discourse.itk.org" rel="noreferrer" \
target="_blank">discourse.itk.org</a>.  Please join us there!<br>
                                    _____________________________<wbr>___<br>
                                    Powered by <a href="http://www.kitware.com" \
rel="noreferrer" target="_blank">www.kitware.com</a><br>  Visit other Kitware \
open-source  projects at<br>
                                    <a \
href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" \
target="_blank">http://www.kitware.com/openso<wbr>urce/opensource.html</a><br>  \
Kitware offers ITK Training  Courses, for more information visit:<br>
                                    <a \
href="http://www.kitware.com/products/protraining.php" rel="noreferrer" \
                target="_blank">http://www.kitware.com/produc<wbr>ts/protraining.php</a><br>
                
                                           Please keep messages on-topic and
                            check the ITK FAQ at:<br>
                                    <a href="http://www.itk.org/Wiki/ITK_FAQ" \
rel="noreferrer" target="_blank">http://www.itk.org/Wiki/ITK_F<wbr>AQ</a><br>  Follow \
this link to  subscribe/unsubscribe:<br>
                                    <a \
href="http://public.kitware.com/mailman/listinfo/insight-users" rel="noreferrer" \
target="_blank">http://public.kitware.com/mai<wbr>lman/listinfo/insight-users</a><br> \
<br>  <br>
                          </blockquote>
                          <br>
                          The ITK community is transitioning from this
                          mailing list to <a href="http://discourse.itk.org" \
rel="noreferrer" target="_blank">discourse.itk.org</a>.  Please join us there!<br>
                          ______________________________<wbr>__<br>
                          Powered by <a href="http://www.kitware.com" \
rel="noreferrer" target="_blank">www.kitware.com</a><br>  <br>
                          Visit other Kitware open-source projects at<br>
                          <a href="http://www.kitware.com/opensource/opensource.html" \
rel="noreferrer" target="_blank">http://www.kitware.com/opensou<wbr>rce/opensource.html</a><br>
  <br>
                          Kitware offers ITK Training Courses, for more
                          information visit:<br>
                          <a href="http://www.kitware.com/products/protraining.php" \
rel="noreferrer" target="_blank">http://www.kitware.com/product<wbr>s/protraining.php</a><br>
  <br>
                          Please keep messages on-topic and check the
                          ITK FAQ at:<br>
                          <a href="http://www.itk.org/Wiki/ITK_FAQ" rel="noreferrer" \
target="_blank">http://www.itk.org/Wiki/ITK_FA<wbr>Q</a><br>  <br>
                          Follow this link to subscribe/unsubscribe:<br>
                          <a \
href="http://public.kitware.com/mailman/listinfo/insight-users" rel="noreferrer" \
target="_blank">http://public.kitware.com/mail<wbr>man/listinfo/insight-users</a><br> \
</div>  </div>
                    </blockquote>
                  </div>
                  <br>
                </div>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </div></div></div>

</blockquote></div><br></div>



The ITK community is transitioning from this mailing list to discourse.itk.org. Please join us there!
________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic