00001 #include <boost/python.hpp>
00002 #include <boost/python/def.hpp>
00003 #include <boost/python/module.hpp>
00004 #include <boost/python/extract.hpp>
00005 #include <boost/python/tuple.hpp>
00006 #include <boost/python/list.hpp>
00007 #include <boost/python/dict.hpp>
00008
00009 #include <iostream>
00010
00011 #include "Net.h"
00012
00013 using namespace boost::python;
00014 using namespace std;
00015
00016 class PyNet : public Net
00017 {
00018 public:
00019 typedef complex<double> cdouble;
00020
00022 PyNet(double d) : Net(d) {}
00023
00025 PyNet(string s) : Net(s.c_str()) {}
00026
00028 ~PyNet() {}
00029
00031 void save(std::string file)
00032 {
00033 Net::save(file.c_str());
00034 }
00035
00037
00038 void generate(dict& d, int max_depth)
00039 {
00040 char msg[128];
00041
00042 int nm = extract<int>(d.attr("__len__")());
00043
00044 cdouble** basis = new cdouble*[nm];
00045 for (int i=0;i<nm;i++)
00046 basis[i] = new cdouble[4];
00047 char* labels = new char[nm];
00048
00049 for (int idx=0;idx<nm;idx++)
00050 {
00051
00052 tuple lm = d.popitem();
00053
00054
00055 labels[idx] = extract<char>(lm[0]);
00056
00057
00058 extract<boost::python::list> ltest(lm[1]);
00059 if (ltest.check())
00060 {
00061 boost::python::list mlist = ltest();
00062
00063
00064 if (extract<int>(mlist.attr("__len__")()) != 4)
00065 {
00066 sprintf(msg,"Object associated with '%c' must be a list"
00067 " of length 4", labels[idx]); throw Exception(msg);
00068 return;
00069 }
00070
00071 basis[idx][0] = extract<cdouble>(mlist[0]);
00072 basis[idx][1] = extract<cdouble>(mlist[1]);
00073 basis[idx][2] = extract<cdouble>(mlist[2]);
00074 basis[idx][3] = extract<cdouble>(mlist[3]);
00075 }
00076
00077 else
00078 {
00079 sprintf(msg,"Object associated with '%c' must be a list"
00080 " of length 4", labels[idx]); throw Exception(msg);
00081 return;
00082 }
00083 }
00084
00085
00086 Net::generate(labels,basis,nm,max_depth);
00087
00088 for (int i=0;i<nm;i++)
00089 delete[] basis[i];
00090 delete[] basis;
00091 delete[] labels;
00092 }
00093
00095
00096 std::string approximate(boost::python::list& m)
00097 {
00098 cdouble elmts[4];
00099
00100 if (extract<int>(m.attr("__len__")()) != 4)
00101 {
00102 char msg[128];
00103 sprintf(msg,"Net::approximate requires a matrix passed as a "
00104 " flat list of length 4"); throw Exception(msg);
00105 return "";
00106 }
00107
00108 elmts[0] = extract<cdouble>(m[0]);
00109 elmts[1] = extract<cdouble>(m[1]);
00110 elmts[2] = extract<cdouble>(m[2]);
00111 elmts[3] = extract<cdouble>(m[3]);
00112
00113 Matrix<cdouble> E(elmts,2,2);
00114
00115 return nearest_string(E);
00116 }
00117
00119 boost::python::list evaluate(std::string s)
00120 {
00121 boost::python::list lm;
00122
00123 Matrix<cdouble> M = Net::evaluate(s);
00124
00125 lm.append(M(0,0));
00126 lm.append(M(0,1));
00127 lm.append(M(1,0));
00128 lm.append(M(1,1));
00129
00130 return lm;
00131 }
00132
00134
00138 boost::python::list solovay_kitaev(boost::python::list& m, int d)
00139 {
00140 cdouble elmts[4];
00141 boost::python::list ret;
00142
00143 if (extract<int>(m.attr("__len__")()) != 4)
00144 {
00145 char msg[128];
00146 sprintf(msg,"Net::approximate requires a matrix passed as a "
00147 " flat list of length 4"); throw Exception(msg);
00148 return ret;
00149 }
00150
00151 elmts[0] = extract<cdouble>(m[0]);
00152 elmts[1] = extract<cdouble>(m[1]);
00153 elmts[2] = extract<cdouble>(m[2]);
00154 elmts[3] = extract<cdouble>(m[3]);
00155
00156 Matrix<cdouble> E(elmts,2,2);
00157
00158 knot ske = Net::solovay_kitaev(E,d);
00159
00160 ret.append(ske.l);
00161 ret.append(ske.word);
00162 ret.append(ske.M(0,0));
00163 ret.append(ske.M(0,1));
00164 ret.append(ske.M(1,0));
00165 ret.append(ske.M(1,1));
00166
00167 return ret;
00168 }
00169
00170 };