Add copy constructor
[platform/core/uifw/ise-engine-sunpinyin.git] / src / slm / slm.h
1 // -*- mode: c++ -*-
2 /*
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4  *
5  * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
6  *
7  * The contents of this file are subject to the terms of either the GNU Lesser
8  * General Public License Version 2.1 only ("LGPL") or the Common Development and
9  * Distribution License ("CDDL")(collectively, the "License"). You may not use this
10  * file except in compliance with the License. You can obtain a copy of the CDDL at
11  * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
12  * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
13  * specific language governing permissions and limitations under the License. When
14  * distributing the software, include this License Header Notice in each file and
15  * include the full text of the License in the License file as well as the
16  * following notice:
17  *
18  * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
19  * (CDDL)
20  * For Covered Software in this distribution, this License shall be governed by the
21  * laws of the State of California (excluding conflict-of-law provisions).
22  * Any litigation relating to this License shall be subject to the jurisdiction of
23  * the Federal Courts of the Northern District of California and the state courts
24  * of the State of California, with venue lying in Santa Clara County, California.
25  *
26  * Contributor(s):
27  *
28  * If you wish your version of this file to be governed by only the CDDL or only
29  * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
30  * include this software in this distribution under the [CDDL or LGPL Version 2.1]
31  * license." If you don't indicate a single choice of license, a recipient has the
32  * option to distribute your version of this file under either the CDDL or the LGPL
33  * Version 2.1, or to extend the choice of license to its licensees as provided
34  * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
35  * Version 2 license, then the option applies only if the new code is made subject
36  * to such option by the copyright holder.
37  */
38
39 #ifndef _SUN_AGC_SLM_H
40 #define _SUN_AGC_SLM_H
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #include "../portability.h"
47
48 #include <stdio.h>
49
50 /**
51  * Thread slm make the following modifications to simple back-off language model
52  *    -# Word id are limited to 18 bits, about 240K word ids
53  *    -# Compact all float value of -log(pr) into 65536 (16 bits)
54  *       level and use a table to map the index to a float value;
55  *    -# Compact all float value of -log(pr) into 16384 (14 bits)
56  *       level and use a table to map the index to a float value;
57  *    -# threading infomation embed into binary model file. Threading include
58  *         - bol(back-off-level) from current level
59  *         - bon(back-off-node)'s index in the bol level array
60  *         .
61  *       The thread could be used:
62  *         - when leaf node are arrived, it could use (bol,bon) as history for
63  *           history node.
64  *         - when a word could not be found in current node (cl, cn)'s children,
65  *           searching could be transfered to (bol, bon) directly and continue
66  *           searching the target word
67  *    -# Add a basic type TState in Language model, a state is pair of\n
68  *           (level, array_idx_of_the level)
69  *    -# change all get probability interface to\n
70  *          double transfer(TState& history, unsigned int wid, TState& result);
71  */
72 class CThreadSlm {
73 public:
74     enum {
75         BITS_BOW        = 14,
76         BITS_PR         = 16,
77         ID_NOT_WORD     = 69,
78     };
79
80     /**
81      * (level:idx) located a state in the language model very well
82      * Please note the psuedo unigram state, with level == 0, but idx > 0
83      * it's for used with bigram cache model
84      */
85     union TState {
86         TState(const TState &b) : m_all(b.m_all) {
87         }
88         TState(unsigned level = 0, unsigned idx = 0) {
89             anony.m_Level = level; anony.m_Idx = idx;
90         }
91
92         TState& operator++()              { ++anony.m_Idx; return *this; }
93
94         void setIdx(unsigned int idx)     { anony.m_Idx = idx; }
95         void setLevel(unsigned int lvl)   { anony.m_Level = lvl; }
96
97         unsigned int getLevel() const { return anony.m_Level; }
98         unsigned int getIdx() const { return anony.m_Idx; }
99         operator unsigned() const { return m_all; }
100
101         bool isTailState() const { return getIdx() <= 1; }
102
103         bool operator==(const TState & b) const {
104             return m_all == b.m_all;
105         }
106         bool operator<(const TState & b) const {
107             return unsigned(*this) < unsigned(b);
108         }
109         TState& operator=(const TState& b) {
110             if (m_all == b.m_all)
111                 return *this;
112
113             m_all = b.m_all;
114             return *this;
115         }
116
117 private:
118         unsigned int m_all;
119 #ifndef WORDS_BIGENDIAN
120         struct TAnonymous {
121             unsigned m_Idx   : 24;
122             unsigned m_Level : 8;
123         } anony;
124 #else
125         struct TAnonymous {
126             unsigned m_Level : 8;
127             unsigned m_Idx   : 24;
128         } anony;
129 #endif
130     };
131
132     /**
133      * Machine dependent
134      */
135     struct TNode {
136 public:
137         unsigned int wid() const {
138             return m_wid;
139         }
140
141         unsigned int bow() const {
142             return m_bow;
143         }
144
145         unsigned int pr()  const {
146             return m_pr;
147         }
148
149         unsigned int bon() const {
150             return m_bon;
151         }
152
153         unsigned int bol() const {
154             return m_bol;
155         }
156
157         unsigned int ch()  const {
158             return((m_ch_hi << 16) + m_ch_lo);
159         }
160
161         void set_wid(unsigned int wid){
162             m_wid = wid;
163         }
164
165         void set_bow(unsigned int bow){
166             m_bow = bow;
167         }
168
169         void set_pr(unsigned int pr){
170             m_pr = pr;
171         }
172
173         void set_bon(unsigned int bon){
174             m_bon = bon;
175         }
176
177         void set_bol(unsigned int bol){
178             m_bol = bol;
179         }
180
181         void set_ch(unsigned int ch){
182             m_ch_hi = ((ch >> 16) & 0x7F);
183             m_ch_lo = (ch & 0xFFFF);
184         }
185
186 protected:
187 #ifndef WORDS_BIGENDIAN
188         unsigned m_wid       : 18;
189         unsigned m_bow       : 14;
190         unsigned m_pr        : 16;
191         unsigned m_ch_lo     : 16;
192         unsigned m_bon       : 23;
193         unsigned m_bol       : 2;
194         unsigned m_ch_hi     : 7;
195 #else
196         unsigned m_ch_hi     : 7;
197         unsigned m_bol       : 2;
198         unsigned m_bon       : 23;
199         unsigned m_ch_lo     : 16;
200         unsigned m_pr        : 16;
201         unsigned m_bow       : 14;
202         unsigned m_wid       : 18;
203 #endif
204
205 private:
206         /**
207          * Machine dependent
208            union TChildIdx {
209            public:
210             inline TChildIdx(unsigned val) : m_all(val) { }
211             inline TChildIdx(const TChildIdx& b) : m_all(b.m_all) { }
212             inline TChildIdx(unsigned int hi, unsigned lo) : m_all(0) { anony.m_hi = hi; anony.m_lo = lo; }
213
214             inline unsigned int lo() { return anony.m_lo; }
215             inline unsigned int hi() { return anony.m_hi; }
216             inline unsigned int all(){ return m_all; }
217
218             inline unsigned int set_lo(unsigned int lo) { return (anony.m_lo = lo); }
219             inline unsigned int set_hi(unsigned int hi) { return (anony.m_hi = hi); }
220             inline unsigned int set_all(unsigned int all) { return (m_all = all); }
221
222            private:
223             unsigned int m_all;
224          *#ifndef WORDS_BIGENDIAN
225             struct TAnony {
226                 unsigned m_lo :16;
227                 unsigned m_hi : 7;
228                 unsigned NOUSE: 9;
229             } anony;
230          *#else
231             struct TAnony {
232                 unsigned NOUSE: 9;
233                 unsigned m_hi : 7;
234                 unsigned m_lo :16;
235             } anony;
236          *#endif
237            };
238          */
239     };
240
241     /**
242      * Machine dependent
243      */
244     struct TLeaf {
245 public:
246         inline unsigned int wid() const { return m_wid; }
247         inline unsigned int bon() const { return m_bon; }
248         inline unsigned int bol() const { return m_bol; }
249         inline unsigned int pr()  const { return((m_pr_hi << 14) + m_pr_lo); }
250
251         inline void set_wid(unsigned int wid) { m_wid = wid; }
252         inline void set_bon(unsigned int bon) { m_bon = bon; }
253         inline void set_bol(unsigned int bol) { m_bol = bol; }
254         inline void set_pr(unsigned int pr)   { m_pr_hi = ((pr >> 14) & 0x3);
255                                                 m_pr_lo = pr & 0x3FFF; }
256
257 protected:
258 #ifndef WORDS_BIGENDIAN
259         unsigned m_wid       : 18;
260         unsigned m_pr_lo     : 14;
261         unsigned m_bon       : 23;
262         unsigned m_bol       : 2;
263         unsigned m_pr_hi     : 2;
264 #else
265         unsigned m_pr_hi     : 2;
266         unsigned m_bol       : 2;
267         unsigned m_bon       : 23;
268         unsigned m_pr_lo     : 14;
269         unsigned m_wid       : 18;
270 #endif
271
272 private:
273         /*
274             union TPr {
275             public:
276                 inline TPr(unsigned int val) : m_all(val) { }
277                 inline TPr(const TPr & b) : m_all(b.m_all) { }
278                 inline TPr(unsigned int hi, unsigned lo) : m_all(0) { anony.m_hi=hi, anony.m_lo=lo; }
279
280                 inline unsigned int lo() { return anony.m_lo; }
281                 inline unsigned int hi() { return anony.m_hi; }
282                 inline unsigned int all(){ return m_all; }
283
284                 inline unsigned int set_lo(unsigned int lo) { return (anony.m_lo = lo); }
285                 inline unsigned int set_hi(unsigned int hi) { return (anony.m_hi = hi); }
286                 inline unsigned int set_all(unsigned int all) { return (m_all = all); }
287
288             private:
289                 unsigned int m_all;
290            #ifndef WORDS_BIGENDIAN
291                 struct TAnony {
292                     unsigned m_lo  :14;
293                     unsigned m_hi  : 2;
294                     unsigned NONUSE:16;
295                 } anony;
296            #else
297                 struct TAnony {
298                     unsigned NONUSE:16;
299                     unsigned m_hi  : 2;
300                     unsigned m_lo  :14;
301                 } anony;
302            #endif
303             };
304          */
305     };
306
307 public:
308     CThreadSlm()
309         : m_N(0), m_UseLogPr(0), m_Levels(NULL), m_LevelSizes(NULL),
310           m_bowTable(NULL), m_prTable(NULL), m_bMMap(false), m_buf(NULL) { }
311
312     ~CThreadSlm() { free(); }
313
314     bool
315     load(const char* fname, bool MMap = false);
316
317     unsigned isUseLogPr() const
318     { return m_UseLogPr; }
319
320     void
321     free();
322
323     double
324     transferNegLog(TState history, unsigned int wid, TState& result);
325
326     double
327     transfer(TState history, unsigned int wid, TState& result);
328
329     TState
330     history_state_of(TState st);
331
332     TState&
333     historify(TState& st);
334
335     unsigned int
336     lastWordId(TState st);
337
338 protected:
339     double
340     rawTransfer(TState history, unsigned int wid, TState& result);
341
342 protected:
343     typedef  void*   PtrVoid;
344
345     unsigned m_N;
346     unsigned m_UseLogPr;
347     void    **m_Levels;
348     unsigned *m_LevelSizes;
349     float    *m_bowTable;
350     float    *m_prTable;
351
352 private:
353     ssize_t m_bufSize;
354     bool m_bMMap;
355     char     *m_buf;
356 };
357
358 #endif