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
|
/* qureg.h: Declarations for qureg.c and inline hashing functions
Copyright 2003-2013 Bjoern Butscher, Hendrik Weimer
This file is part of libquantum
libquantum 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.
libquantum 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 libquantum; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA
*/
#ifndef __QUREG_H
#define __QUREG_H
#include <sys/types.h>
#include "config.h"
#include "matrix.h"
#include "error.h"
/* The quantum register */
struct quantum_reg_struct
{
int width; /* number of qubits in the qureg */
int size; /* number of non-zero vectors */
int hashw; /* width of the hash array */
COMPLEX_FLOAT *amplitude;
MAX_UNSIGNED *state;
int *hash;
};
typedef struct quantum_reg_struct quantum_reg;
extern quantum_reg quantum_matrix2qureg(quantum_matrix *m, int width);
extern quantum_reg quantum_new_qureg(MAX_UNSIGNED initval, int width);
extern quantum_reg quantum_new_qureg_size(int n, int width);
extern quantum_reg quantum_new_qureg_sparse(int n, int width);
extern quantum_matrix quantum_qureg2matrix(quantum_reg reg);
extern void quantum_destroy_hash(quantum_reg *reg);
extern void quantum_delete_qureg(quantum_reg *reg);
extern void quantum_delete_qureg_hashpreserve(quantum_reg *reg);
extern void quantum_copy_qureg(quantum_reg *src, quantum_reg *dst);
extern void quantum_print_qureg(quantum_reg reg);
extern void quantum_print_expn(quantum_reg reg);
extern void quantum_addscratch(int bits, quantum_reg *reg);
extern void quantum_print_hash(quantum_reg reg);
extern quantum_reg quantum_kronecker(quantum_reg *reg1, quantum_reg *reg2);
extern quantum_reg quantum_state_collapse(int bit, int value,
quantum_reg reg);
extern COMPLEX_FLOAT quantum_dot_product(quantum_reg *reg1, quantum_reg *reg2);
extern quantum_reg quantum_vectoradd(quantum_reg *reg1, quantum_reg *reg2);
extern void quantum_vectoradd_inplace(quantum_reg *reg1, quantum_reg *reg2);
extern quantum_reg quantum_matrix_qureg(quantum_reg A(MAX_UNSIGNED, double),
double t, quantum_reg *reg, int flags);
extern void quantum_scalar_qureg(COMPLEX_FLOAT r, quantum_reg *reg);
extern void quantum_mvmult(quantum_reg *y, quantum_matrix A, quantum_reg *x);
extern void quantum_print_timeop(int width, void f(quantum_reg *));
extern void quantum_normalize(quantum_reg *reg);
/* Our 64-bit multiplicative hash function */
static inline unsigned int
quantum_hash64(MAX_UNSIGNED key, int width)
{
unsigned int k32;
k32 = (key & 0xFFFFFFFF) ^ (key >> 32);
k32 *= 0x9e370001UL;
k32 = k32 >> (32-width);
return k32;
}
/* Get the position of a given base state via the hash table */
static inline int
quantum_get_state(MAX_UNSIGNED a, quantum_reg reg)
{
int i;
if(!reg.hashw)
return a;
i = quantum_hash64(a, reg.hashw);
while(reg.hash[i])
{
if(reg.state[reg.hash[i]-1] == a)
return reg.hash[i]-1;
i++;
if(i == (1 << reg.hashw))
i = 0;
}
return -1;
}
/* Add an element to the hash table */
static inline void
quantum_add_hash(MAX_UNSIGNED a, int pos, quantum_reg *reg)
{
int i, mark = 0;
i = quantum_hash64(a, reg->hashw);
while(reg->hash[i])
{
i++;
if(i == (1 << reg->hashw))
{
if(!mark)
{
i = 0;
mark = 1;
}
else
quantum_error(QUANTUM_EHASHFULL);
}
}
reg->hash[i] = pos+1;
}
/* Reconstruct hash table */
static inline void
quantum_reconstruct_hash(quantum_reg *reg)
{
int i;
/* Check whether register is sorted */
if(!reg->hashw)
return;
for(i=0; i<(1 << reg->hashw); i++)
reg->hash[i] = 0;
for(i=0; i<reg->size; i++)
quantum_add_hash(reg->state[i], i, reg);
}
/* Return the reduced bitmask of a basis state */
static inline int
quantum_bitmask(MAX_UNSIGNED a, int width, int *bits)
{
int i;
int mask = 0;
for(i=0; i<width; i++)
{
if(a & ((MAX_UNSIGNED) 1 << bits[i]))
mask += 1 << i;
}
return mask;
}
#endif
|