inline struct map_type *multiplicate( struct map_type *map,
                               struct map_type *map_2 )
{
    int i, j, k;
    __float128 sum_tmp;
    struct map_type *result;

    if( ( map->i_size == 1 && map->j_size == 1 )
        && ( map_2->i_size > 1 || map_2->j_size > 1 ) )
    {
        result = multiplicate_on_value( *( *( map->memory + 0 ) + 0 ), map_2 );
    }
    else
    {
        result = allocate( map->i_size, map_2->j_size );
        for( i = 0; i < map->i_size; i++ )
        {
            for( j = 0; j < map_2->j_size; j++ )
            {
                for( sum_tmp = 0, k = 0; k < map->j_size; k++ )
                {
                    sum_tmp += *( *( map->memory + i ) + k ) * ( *( *( map_2->memory + k ) + j ) );
                }
                *( *( result->memory + i ) + j ) = sum_tmp;
            }
        }
    }
    return result;
}
inline struct map_type *subtraction( struct map_type *map,
                              struct map_type *map_2 )
{
    struct map_type *tmp, *result;
    tmp = multiplicate_on_value( -1, map_2 );
    result = addition( map, tmp );
    deallocate( tmp );
    return result;
}
inline struct map_type *get_inverse( struct map_type *map )
{
    struct map_type *result;
    if( map->i_size == 1
        && map->j_size == 1 )
    {
        result = allocate( 2, 2 );
        result->i_size = 1;
        result->j_size = 1;
        __float128 value = *( *( map->memory + 0 ) + 0 );
        *( *( result->memory + 0 ) + 0 ) = value == 0 ? 0 : powf( value, -1 );
    }
    else
    {
        __float128 determinant = get_determinant( map );
        result = multiplicate_on_value( powf( determinant, -1 ), map );
    }
    return result;
}
示例#4
0
struct map_type *dfp( function func,
                      struct map_type *map_x,
                      __float128 grad_toler,
                      __float128 fx_toler,
                      const unsigned int max_iter )
{
    unsigned int iter;
    __float128 lambda, result_func_value, temp_func_value;
    struct map_type *result, *b, *grad1, *tmp, *s, *grad2,
            *g, *tmp2, *tmp3, *d, *x1, *x2, *x3, *x4, *x5;

    result = NULL;
    result_func_value = func( map_x );

    b = get_identity_matrix( map_x->j_size );
    grad1 = first_derivatives( func, map_x );
    tmp = transposition( grad1 );
    deallocate( grad1 );
    grad1 = tmp;
    for( iter = 0 ; iter < max_iter; iter++ )
	{
        tmp = multiplicate_on_value( -1, b );
        s = multiplicate( tmp, grad1 );
        deallocate( tmp );

        tmp = transposition( s );
        tmp2 = multiplicate_on_value( powf( get_euclidean_distance( s ), -1 ), tmp );
        deallocate( s );
        deallocate( tmp );
        s = tmp2;

        lambda = 1;
        lambda = line_search( func, map_x, lambda, s );
        d = multiplicate_on_value( lambda, s );

        tmp = addition( map_x, d );
        deallocate( d );
        deallocate( map_x );
        map_x = tmp;
        temp_func_value = func( map_x );
        if( result_func_value > temp_func_value )
        {
            iter = 0;
            result_func_value = temp_func_value;
            if( result != NULL )
            {
                deallocate( result );
            }
            result = clone( map_x );
        }

        grad2 = first_derivatives( func, map_x );
        tmp = transposition( grad2 );
        deallocate( grad2 );
        grad2 = tmp;
        g = subtraction( grad2, grad1 );
        deallocate( grad1 );
        grad1 = grad2;
        if( get_euclidean_distance( grad1 ) < grad_toler )
        {
            /// TODO: Нужно очистить память
            break;
        }

        tmp = transposition( s );
        x1 = multiplicate( s, tmp );
        x2 = multiplicate( s, g );
        deallocate( s );
        deallocate( tmp );

        tmp = multiplicate_on_value( lambda, x1 );
        tmp2 = get_inverse( x2 );
        tmp3 = multiplicate( tmp, tmp2 );
        deallocate( tmp );
        tmp = addition( b, tmp3 );
        deallocate( x1 );
        deallocate( x2 );
        deallocate( tmp2 );
        deallocate( tmp3 );
        deallocate( b );
        b = tmp;

        x3 = multiplicate( b, g );
        tmp = transposition( b );
        x4 = multiplicate( tmp, g );
        deallocate( tmp );

        tmp = transposition( g );
        tmp2 = multiplicate( tmp, b );
        x5 = multiplicate( tmp2, g );
        deallocate( g );
        deallocate( tmp );
        deallocate( tmp2 );

        tmp = transposition( x4 );
        tmp2 = multiplicate( x3, tmp );
        deallocate( tmp );
        tmp = get_inverse( x5 );
        tmp3 = multiplicate( tmp, tmp2 );
        deallocate( tmp );

        tmp = subtraction( b, tmp3 );
        deallocate( b );
        b = tmp;

        deallocate( tmp2 );
        deallocate( tmp3 );
        deallocate( x3 );
        deallocate( x4 );
        deallocate( x5 );
    }
    return result;
}