/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ---- includes ----------------------------------------------------------- */
#include "b_APIEm/Functions.h"
#include "b_BasicEm/Memory.h"
/* ---- related objects --------------------------------------------------- */
/* ---- typedefs ----------------------------------------------------------- */
/* ---- constants ---------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
/* */
/* ---- \ghd{ external functions } ----------------------------------------- */
/* */
/* ========================================================================= */
/* ------------------------------------------------------------------------- */
void bpi_normalizeSimilarities( struct bbs_Context* cpA,
const int32* rawSimArrA,
const int32* rawIdArrA,
uint32 rawSizeA,
const int32* refSimArrA,
const int32* refIdArrA,
uint32 refSizeA,
enum bpi_SimType simTypeA,
int32* outSimArrA )
{
/* 8.24 */
int32 refSimL = 0;
uint32 iL, jL, kL;
int32* outPtrL = outSimArrA;
const int32* rawPtrL = rawSimArrA;
switch( simTypeA )
{
case bpi_RAW_SIM:
{
/* nothing to do */
}
break;
case bpi_SUB_MEAN:
{
int32 shiftL = 0;
int32 roundL = 0;
refSimL = 0;
for( iL = 0; iL < refSizeA; iL++ )
{
refSimL += ( refSimArrA[ iL ] + roundL ) >> shiftL;
if( refSimL > 0x40000000 )
{
refSimL = ( refSimL + 1 ) >> 1;
shiftL++;
roundL = ( int32 )1 << ( shiftL - 1 );
}
}
refSimL = ( refSimL / refSizeA ) << shiftL;
}
break;
case bpi_SUB_MAX_2:
{
int32 maxL = 0;
uint32 maxIndexL = 0;
int32 idL = 0;
/* find raw maximum */
for( iL = 0; iL < rawSizeA; iL++ )
{
if( maxL < rawSimArrA[ iL ] )
{
maxL = refSimArrA[ iL ];
maxIndexL = iL;
}
}
/* consider id of maximum equal to probe id */
idL = rawIdArrA[ maxIndexL ];
/* find maximum similarity in ref array of different id */
for( iL = 0; iL < refSizeA; iL++ )
{
if( refIdArrA[ iL ] != idL )
{
refSimL = ( refSimL > refSimArrA[ iL ] ) ? refSimL : refSimArrA[ iL ];
}
}
}
break;
case bpi_SUB_16_MAX_2:
{
int32 maxL = 0;
uint32 maxIndexL = 0;
int32 idL = 0;
int32 maxSimArrL[ 16 ];
bbs_memset32( maxSimArrL, ( uint32 )-1, bbs_SIZEOF32( maxSimArrL ) );
/* find raw maximum */
for( iL = 0; iL < rawSizeA; iL++ )
{
if( maxL < rawSimArrA[ iL ] )
{
maxL = rawSimArrA[ iL ];
maxIndexL = iL;
}
}
/* consider id of maximum equal to probe id */
idL = rawIdArrA[ maxIndexL ];
/* find 16 maximum similarities of different id in ref array */
for( iL = 0; iL < refSizeA; iL++ )
{
if( refIdArrA[ iL ] != idL )
{
int32 simL = refSimArrA[ iL ];
for( jL = 0; jL < 16; jL++ )
{
if( simL > maxSimArrL[ jL ] ) break;
}
for( kL = 15; kL > jL; kL-- )
{
maxSimArrL[ kL ] = maxSimArrL[ kL - 1 ];
}
if( jL < 16 ) maxSimArrL[ jL ] = simL;
}
}
refSimL = 0;
for( jL = 0; jL < 16; jL++ )
{
if( maxSimArrL[ jL ] == -1 ) break;
refSimL += maxSimArrL[ jL ];
}
if( jL > 0 )
{
refSimL /= jL;
}
}
break;
default:
{
bbs_ERROR1( "void bpi_Identifier_normalizeSimilarities(): simTypeA '%i' is handled", simTypeA );
return;
}
}
/* refSimL -= 1.0 */
refSimL -= ( (uint32)1 << 24 );
for( iL = rawSizeA; iL > 0; iL-- )
{
*outPtrL++ = ( *rawPtrL++ - refSimL + 1 ) >> 1;
}
}
/* ------------------------------------------------------------------------- */
int32 bpi_normalizedSimilarity( struct bbs_Context* cpA,
int32 rawSimA,
int32 rawIdA,
const int32* refSimArrA,
const int32* refIdArrA,
uint32 refSizeA,
enum bpi_SimType simTypeA )
{
/* 8.24 */
int32 refSimL = 0;
uint32 iL, jL, kL;
switch( simTypeA )
{
case bpi_RAW_SIM:
{
/* nothing to do */
return rawSimA; /* return without adjustment of value range */
}
case bpi_SUB_MEAN:
{
int32 shiftL = 0;
int32 roundL = 0;
refSimL = 0;
for( iL = 0; iL < refSizeA; iL++ )
{
refSimL += ( refSimArrA[ iL ] + roundL ) >> shiftL;
if( refSimL > 0x40000000 )
{
refSimL = ( refSimL + 1 ) >> 1;
shiftL++;
roundL = ( int32 )1 << ( shiftL - 1 );
}
}
refSimL = ( refSimL / refSizeA ) << shiftL;
}
break;
case bpi_SUB_MAX_2:
{
/* find maximum similarity in ref array of different rawIdA */
for( iL = 0; iL < refSizeA; iL++ )
{
if( refIdArrA[ iL ] != rawIdA )
{
refSimL = ( refSimL > refSimArrA[ iL ] ) ? refSimL : refSimArrA[ iL ];
}
}
}
break;
case bpi_SUB_16_MAX_2:
{
int32 maxSimArrL[ 16 ];
int32 idL = rawIdA;
bbs_memset32( maxSimArrL, ( uint32 )-1, bbs_SIZEOF32( maxSimArrL ) );
/* find 16 maximum similarities of different id in ref array */
for( iL = 0; iL < refSizeA; iL++ )
{
if( refIdArrA[ iL ] != idL )
{
int32 simL = refSimArrA[ iL ];
for( jL = 0; jL < 16; jL++ )
{
if( simL > maxSimArrL[ jL ] ) break;
}
for( kL = 15; kL > jL; kL-- )
{
maxSimArrL[ kL ] = maxSimArrL[ kL - 1 ];
}
if( jL < 16 ) maxSimArrL[ jL ] = simL;
}
}
refSimL = 0;
for( jL = 0; jL < 16; jL++ )
{
if( maxSimArrL[ jL ] == -1 ) break;
refSimL += maxSimArrL[ jL ];
}
if( jL > 0 )
{
refSimL /= jL;
}
}
break;
default:
{
bbs_ERROR1( "void bpi_Identifier_normalizeSimilarities(): simTypeA '%i' is handled", simTypeA );
}
break;
}
/* refSimL -= 1.0 */
refSimL -= ( (uint32)1 << 24 );
return ( rawSimA - refSimL + 1 ) >> 1;
}
/* ------------------------------------------------------------------------- */
uint32 bpi_memWriteCsa16( uint16* memPtrA, uint32 memSizeA, uint16 chkSumA )
{
uint16* memPtrL = memPtrA - memSizeA + 1;
uint32 iL;
uint16 sumL = 0;
uint16 csaL = 0;
bbs_memWrite16( &csaL, memPtrA );
for( iL = 0; iL < memSizeA; iL++ )
{
uint16 valL = 0;
memPtrL += bbs_memRead16( &valL, memPtrL );
sumL += valL;
}
csaL = chkSumA - sumL;
return bbs_memWrite16( &csaL, memPtrA );
}
/* ------------------------------------------------------------------------- */
uint32 bpi_memReadCsa16( const uint16* memPtrA )
{
return bbs_SIZEOF16( uint16 );
}
/* ------------------------------------------------------------------------- */