summaryrefslogtreecommitdiffstats
path: root/src/lookup/phonetic_lookup_heap.h
blob: 94f97d1a383af3d70aa81a9094e4998cc0b36274 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* 
 *  libpinyin
 *  Library to deal with pinyin.
 *  
 *  Copyright (C) 2017 Peng Wu <alexepico@gmail.com>
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef PHONETIC_LOOKUP_HEAP_H
#define PHONETIC_LOOKUP_HEAP_H

static inline bool trellis_value_more_than(const trellis_value_t &lhs,
                                           const trellis_value_t &rhs) {
    /* min heap here */
    return lhs.m_poss > rhs.m_poss;
}

template <gint32 nbest>
struct trellis_node {
private:
    gint32 m_nelem;
    /* invariant: min heap */
    trellis_value_t m_elements[nbest];

public:
    trellis_node(){
        m_nelem = 0;
        /* always assume non-used m_elements contains random data. */
    }

public:
    gint32 length() { return m_nelem; }
    const trellis_value_t * begin() { return m_elements; }
    const trellis_value_t * end() { return m_elements + m_nelem; }

    bool number() {
        for (ssize_t i = 0; i < m_nelem; ++i)
            m_elements[i].m_current_index = i;
    }

    /* return true if the item is stored into m_elements. */
    bool eval_item(const trellis_value_t * item) {
        /* min heap here, and always push heap. */

        /* still have space */
        if (m_nelem < nbest) {
            m_elements[m_nelem] = *item;
            m_nelem ++;
            push_heap(begin(), end(), trellis_value_more_than);
            return true;
        }

        /* find minium item */
        trellis_value_t * min = m_elements;

        /* compare new item */
        if (item->m_poss > min->m_poss) {
            pop_heap(begin(), end(), trellis_value_more_than);
            m_elements[m_nelem - 1] = *item;
            push_heap(begin(), end(), trellis_value_more_than);
            return true;
        }

        return false;
    }
};

/* for space usage and performance. */
/* as trellis node only contains one element,
 * when the trellis node created, always put one element in it.
 * when no trellis node, it represents zero element.
 */
template <>
struct trellis_node <1> {
private:
    trellis_value_t m_element;

public:
    trellis_node <1> () : m_element(-FLT_MAX) {}

public:
    gint32 length() { return 1; }
    const trellis_value_t * begin() { return &m_element; }
    const trellis_value_t * end() { return &m_element + 1; }

    /* return true if the item is stored into m_element. */
    bool eval_item(const trellis_value_t * item) {
        if (item->m_poss > m_element.m_poss) {
            m_element = *item;
            return true;
        }

        return false;
    }
};


#if 0
static inline bool matrix_value_more_than(const matrix_value_t &lhs,
                                          const matrix_value_t &rhs) {
    /* min heap here */
    return lhs.m_poss > rhs.m_poss;
}

template <gint32 nbest>
struct matrix_step {
private:
    gint32 m_nelem;
    /* invariant: min heap */
    matrix_value_t m_elements[nbest];

public:
    matrix_step(){
        m_nelem = 0;
        /* always assume non-used m_elements contains random data. */
    }

public:
    gint32 length() { return m_nelem; }
    const matrix_value_t * begin() { return m_elements; }
    const matrix_value_t * end() { return m_elements + m_nelem; }

    /* return true if the item is stored into m_elements. */
    bool eval_item(const matrix_value_t * item) {
        /* min heap here, and always push heap. */

        /* still have space */
        if (m_nelem < nbest) {
            m_elements[m_nelem] = *item;
            m_nelem ++;
            push_heap(begin(), end(), matrix_value_more_than);
            return true;
        }

        /* find minium item */
        matrix_value_t * min = m_elements;

        /* compare new item */
        if (item->m_poss > min->m_poss) {
            pop_heap(begin(), end(), matrix_value_more_than);
            m_elements[m_nelem - 1] = *item;
            push_heap(begin(), end(), matrix_value_more_than);
            return true;
        }

        return false;
    }
};

/* for space usage and performance. */
/* as matrix step contains only one element,
   initialize with empty element. */
template <>
struct matrix_step <1> {
private:
    matrix_value_t m_element;

public:
    matrix_step <1> () : m_element(-FLT_MAX) {}

public:
    gint32 length() { return 1; }
    const matrix_value_t * begin() { return &m_element; }
    const matrix_value_t * end() { return &m_element + 1; }

    /* return true if the item is stored into m_element. */
    bool eval_item(const matrix_value_t * item) {
        if (item->m_poss > m_element.m_poss) {
            m_element = *item;
            return true;
        }

        return false;
    }
};
#endif


#endif