1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// sparse-power-weight.h 2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License"); 4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License. 5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at 6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// http://www.apache.org/licenses/LICENSE-2.0 8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software 10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS, 11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and 13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License. 14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc. 16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: krr@google.com (Kasturi Rangan Raghavan) 17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Inspiration: allauzen@google.com (Cyril Allauzen) 18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Cartesian power weight semiring operation definitions. 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Uses SparseTupleWeight as underlying representation. 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_SPARSE_POWER_WEIGHT_H__ 24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_SPARSE_POWER_WEIGHT_H__ 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include<string> 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/sparse-tuple-weight.h> 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/weight.h> 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst { 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Below SparseTupleWeight*Mapper are used in conjunction with 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// SparseTupleWeightMap to compute the respective semiring operations 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class W, class K> 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct SparseTupleWeightPlusMapper { 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson W Map(const K& k, const W& v1, const W& v2) const { 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Plus(v1, v2); 40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class W, class K> 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct SparseTupleWeightTimesMapper { 45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson W Map(const K& k, const W& v1, const W& v2) const { 46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times(v1, v2); 47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class W, class K> 51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct SparseTupleWeightDivideMapper { 52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightDivideMapper(DivideType divide_type) { 53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson divide_type_ = divide_type; 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson W Map(const K& k, const W& v1, const W& v2) const { 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide(v1, v2, divide_type_); 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType divide_type_; 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class W, class K> 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonstruct SparseTupleWeightApproxMapper { 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightApproxMapper(float delta) { delta_ = delta; } 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson W Map(const K& k, const W& v1, const W& v2) const { 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ApproxEqual(v1, v2, delta_) ? W::One() : W::Zero(); 66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson float delta_; 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Sparse cartesian power semiring: W ^ n 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Forms: 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - a left semimodule when W is a left semiring, 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - a right semimodule when W is a right semiring, 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - a bisemimodule when W is a semiring, 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// the free semimodule of rank n over W 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The Times operation is overloaded to provide the 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// left and right scalar products. 78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// K is the key value type. kNoKey(-1) is reserved for internal use 79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K = int> 80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass SparsePowerWeight : public SparseTupleWeight<W, K> { 81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using SparseTupleWeight<W, K>::Zero; 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using SparseTupleWeight<W, K>::One; 84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using SparseTupleWeight<W, K>::NoWeight; 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using SparseTupleWeight<W, K>::Quantize; 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson using SparseTupleWeight<W, K>::Reverse; 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef SparsePowerWeight<typename W::ReverseWeight, K> ReverseWeight; 89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight() {} 91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight(const SparseTupleWeight<W, K> &w) : 93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeight<W, K>(w) { } 94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson template <class Iterator> 96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight(Iterator begin, Iterator end) : 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeight<W, K>(begin, end) { } 98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight(const K &key, const W &w) : 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeight<W, K>(key, w) { } 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const SparsePowerWeight<W, K> &Zero() { 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const SparsePowerWeight<W, K> zero(SparseTupleWeight<W, K>::Zero()); 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return zero; 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const SparsePowerWeight<W, K> &One() { 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const SparsePowerWeight<W, K> one(SparseTupleWeight<W, K>::One()); 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return one; 110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const SparsePowerWeight<W, K> &NoWeight() { 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const SparsePowerWeight<W, K> no_weight( 114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeight<W, K>::NoWeight()); 115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return no_weight; 116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Overide this: Overwrite the Type method to reflect the key type 119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // if using non-default key type. 120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static const string &Type() { 121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static string type; 122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if(type.empty()) { 123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson type = W::Type() + "_^n"; 124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if(sizeof(K) != sizeof(uint32)) { 125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson string size; 126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Int64ToStr(8 * sizeof(K), &size); 127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson type += "_" + size; 128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return type; 131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson static uint64 Properties() { 134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 props = W::Properties(); 135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return props & (kLeftSemiring | kRightSemiring | 136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kCommutative | kIdempotent); 137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight<W, K> Quantize(float delta = kDelta) const { 140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return SparseTupleWeight<W, K>::Quantize(delta); 141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ReverseWeight Reverse() const { 144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return SparseTupleWeight<W, K>::Reverse(); 145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Semimodule plus operation 149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline SparsePowerWeight<W, K> Plus(const SparsePowerWeight<W, K> &w1, 151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const SparsePowerWeight<W, K> &w2) { 152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight<W, K> ret; 153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightPlusMapper<W, K> operator_mapper; 154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightMap(&ret, w1, w2, operator_mapper); 155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ret; 156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Semimodule times operation 159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline SparsePowerWeight<W, K> Times(const SparsePowerWeight<W, K> &w1, 161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const SparsePowerWeight<W, K> &w2) { 162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight<W, K> ret; 163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightTimesMapper<W, K> operator_mapper; 164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightMap(&ret, w1, w2, operator_mapper); 165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ret; 166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Semimodule divide operation 169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline SparsePowerWeight<W, K> Divide(const SparsePowerWeight<W, K> &w1, 171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const SparsePowerWeight<W, K> &w2, 172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType type = DIVIDE_ANY) { 173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight<W, K> ret; 174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightDivideMapper<W, K> operator_mapper(type); 175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightMap(&ret, w1, w2, operator_mapper); 176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ret; 177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Semimodule dot product 180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline const W& DotProduct(const SparsePowerWeight<W, K> &w1, 182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const SparsePowerWeight<W, K> &w2) { 183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const SparsePowerWeight<W, K>& product = Times(w1, w2); 184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson W ret(W::Zero()); 185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson for (SparseTupleWeightIterator<W, K> it(product); !it.Done(); it.Next()) { 186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ret = Plus(ret, it.Value().second); 187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ret; 189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool ApproxEqual(const SparsePowerWeight<W, K> &w1, 193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const SparsePowerWeight<W, K> &w2, 194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson float delta = kDelta) { 195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeight<W, K> ret; 196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightApproxMapper<W, K> operator_mapper(kDelta); 197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparseTupleWeightMap(&ret, w1, w2, operator_mapper); 198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ret == SparsePowerWeight<W, K>::One(); 199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline SparsePowerWeight<W, K> Times(const W &k, 203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const SparsePowerWeight<W, K> &w2) { 204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight<W, K> w1(k); 205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times(w1, w2); 206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline SparsePowerWeight<W, K> Times(const SparsePowerWeight<W, K> &w1, 210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const W &k) { 211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight<W, K> w2(k); 212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Times(w1, w2); 213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class W, class K> 216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline SparsePowerWeight<W, K> Divide(const SparsePowerWeight<W, K> &w1, 217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const W &k, 218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DivideType divide_type = DIVIDE_ANY) { 219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SparsePowerWeight<W, K> w2(k); 220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Divide(w1, w2, divide_type); 221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace fst 224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif // FST_LIB_SPARSE_POWER_WEIGHT_H__ 226