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 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
|
/*
* Copyright (c) 2009 Samit Basu
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "Operators.hpp"
#include "Array.hpp"
#include "SparseMatrix.hpp"
struct OpBitAnd {
template <typename T>
static inline T func(T A, T B) {return T(uint32(A) & uint32(B));}
template <typename T>
static inline void func(const T& Ar, const T& Ai,
const T& Br, const T& Bi,
T& cr, T& ci) {
cr = T(uint32(Ar) & uint32(Br));
ci = T(uint32(Ai) & uint32(Bi));
}
};
struct OpBitOr {
template <typename T>
static inline T func(T A, T B) {return T(uint32(A) | uint32(B));}
template <typename T>
static inline void func(const T& Ar, const T& Ai,
const T& Br, const T& Bi,
T& cr, T& ci) {
cr = T(uint32(Ar) | uint32(Br));
ci = T(uint32(Ai) | uint32(Bi));
}
};
struct OpBitXor {
template <typename T>
static inline T func(T A, T B) {return T(uint32(A) ^ uint32(B));}
template <typename T>
static inline void func(const T& Ar, const T& Ai,
const T& Br, const T& Bi,
T& cr, T& ci) {
cr = T(uint32(Ar) ^ uint32(Br));
ci = T(uint32(Ai) ^ uint32(Bi));
}
};
struct OpBitCmp {
template <typename T>
static inline T func(T A) {return T(~A);}
template <typename T>
static inline void func(const T &Ar, const T &Ai, T& Cr, T& Ci) {
Cr = T(~uint32(Ar));
Ci = T(~uint32(Ai));
}
};
//@@Signature
//function bitand BitandFunction jitsafe
//inputs a b
//outputs y
//DOCBLOCK binary_bitand
ArrayVector BitandFunction(int nargout, const ArrayVector& arg) {
if (arg.size() < 2)
throw Exception("bitand requires at least two arguments");
return ArrayVector(DotOp<OpBitAnd>(arg[0],arg[1]));
}
JitScalarFunc2(bitand,OpBitAnd::func);
//@@Signature
//function bitor BitorFunction jitsafe
//inputs a b
//outputs y
//DOCBLOCK binary_bitor
ArrayVector BitorFunction(int nargout, const ArrayVector& arg) {
if (arg.size() < 2)
throw Exception("bitor requires at least two arguments");
return ArrayVector(DotOp<OpBitOr>(arg[0],arg[1]));
}
JitScalarFunc2(bitor,OpBitOr::func);
//@@Signature
//function bitxor BitxorFunction jitsafe
//inputs a b
//outputs y
//DOCBLOCK binary_bitxor
ArrayVector BitxorFunction(int nargout, const ArrayVector& arg) {
if (arg.size() < 2)
throw Exception("bitxor requires at least two arguments");
return ArrayVector(DotOp<OpBitXor>(arg[0],arg[1]));
}
JitScalarFunc2(bitxor,OpBitXor::func);
//@@Signature
//function bitcmp BitcmpFunction jitsafe
//inputs a n
//outputs y
//DOCBLOCK binary_bitcmp
template <typename T>
static Array TBitCmpFunc(const BasicArray<T> &x, double maxval) {
BasicArray<T> y(x.dimensions());
for (index_t i=1;i<=y.length();i++) {
y[i] = maxval - 1 - x[i];
}
return Array(y);
}
#define MacroBitCmp(ctype,cls) \
case cls: return ArrayVector(TBitCmpFunc<ctype>(y.constReal<ctype>(),maxval));
ArrayVector BitcmpFunction(int nargout, const ArrayVector& arg) {
if (arg.size() < 1)
return ArrayVector(Array());
if (arg.size() == 1) {
switch (arg[0].dataClass()) {
case UInt8: return ArrayVector(UnaryOp<uint8,OpBitCmp>(arg[0],UInt8));
case UInt16: return ArrayVector(UnaryOp<uint16,OpBitCmp>(arg[0],UInt16));
case UInt32: return ArrayVector(UnaryOp<uint32,OpBitCmp>(arg[0],UInt32));
case UInt64: return ArrayVector(UnaryOp<uint64,OpBitCmp>(arg[0],UInt64));
default:
throw Exception("bitcmp is only defiled for unsigned integer types.");
}
}
int bits = arg[1].asInteger();
if (bits <= 0) throw Exception("bitcmp bits must be positive");
double maxval = pow(2.0,double(bits));
if (!IsInteger(arg[0])) throw Exception("bitcmp can only be applied to integer arguments");
if (!IsNonNegative(arg[0])) throw Exception("bitcmp argument must be nonnegative");
if (arg[0].isComplex()) throw Exception("bitcmp argument must be real valued");
if (arg[0].isSparse()) throw Exception("bitcmp is not defined for sparse matrices");
Array y(arg[0]);
y.ensureNotScalarEncoded();
switch (arg[0].dataClass()) {
default:
throw Exception("type not supported by bitcmp");
MacroExpandCasesNoBool(MacroBitCmp);
}
}
//@@Signature
//function int2bin Int2BinFunction
//inputs x bits
//outputs y
//DOCBLOCK typecast_int2bin
struct OpInt2Bin {
template <typename T>
static inline void func(const ConstSparseIterator<T> &, SparseSlice<T>&) {
throw Exception("int2bin not supported for sparse matrices");
}
template <typename T>
static inline void func(const ConstComplexSparseIterator<T> &,
SparseSlice<T>&, SparseSlice<T>&) {
throw Exception("int2bin not supported for sparse matrices");
}
template <typename T>
static inline void func(const BasicArray<T> &src, BasicArray<T>& dest) {
int numbits = int(dest.length());
if (numbits < 1) numbits = 1;
int64 value = int64(src[1]);
for (int i=0;i<numbits;i++) {
dest[numbits-i] = T(value & 1);
value >>= 1;
}
}
template <typename T>
static inline void func(const BasicArray<T> &src_real, const BasicArray<T> &src_imag,
BasicArray<T>& dest_real, BasicArray<T>& dest_imag) {
func(src_real,dest_real);
func(src_imag,dest_imag);
}
};
ArrayVector Int2BinFunction(int nargout, const ArrayVector& arg) {
if (arg.size() < 2)
throw Exception("int2bin requires at least two arguments");
int n = arg[1].asInteger();
n = qMax(0,qMin(64,n));
return ArrayVector(VectorOp<OpInt2Bin>(arg[0],n,
qMax(1,arg[0].dimensions().lastSingular())).toClass(Bool));
}
//@@Signature
//function bin2int Bin2IntFunction
//inputs x flag
//outputs y
//DOCBLOCK typecast_bin2int
struct OpBin2Int {
template <typename T>
static inline void func(const ConstSparseIterator<T> &, SparseSlice<T>&) {
throw Exception("int2bin not supported for sparse matrices");
}
template <typename T>
static inline void func(const ConstComplexSparseIterator<T> &,
SparseSlice<T>&, SparseSlice<T>&) {
throw Exception("int2bin not supported for sparse matrices");
}
template <typename T>
static inline void func(const BasicArray<T> &src, BasicArray<T>& dest) {
int numbits = int(src.length());
uint64 value = (src[1] != 0) ? 1 : 0;
for (int j=1;j<numbits;j++) {
value <<= 1;
value |= (src[j+1] != 0) ? 1 : 0;
}
dest[1] = value;
}
template <typename T>
static inline void func(const BasicArray<T> &src_real, const BasicArray<T> &src_imag,
BasicArray<T>& dest_real, BasicArray<T>& dest_imag) {
func(src_real,dest_real);
func(src_imag,dest_imag);
}
};
ArrayVector Bin2IntFunction(int nargout, const ArrayVector& arg) {
if (arg.size() < 1)
throw Exception("bin2int requires at least one arguments");
if ((arg.size() == 2) && (arg[1].asString().toUpper() == "SIGNED"))
return ArrayVector(VectorOp<OpBin2Int>(arg[0].toClass(Int32),1,
arg[0].dimensions().lastNotOne()-1));
else
return ArrayVector(VectorOp<OpBin2Int>(arg[0].toClass(UInt32),1,
arg[0].dimensions().lastNotOne()-1));
}
|