defdwave_run_embedding(data,label,path_in,annealing_times,chain_strengths,em_id,solver='Advantage_system1.1'):#em_id is a label for the embedding. In this way, it is possible to re-run a previously computed and stored embedding with e.g. different chain strength and/or annealing time
MAXRESULTS=20# NOTE: to save space only 20 best results
qubo_nodes=np.array([[i,i,(qubo_nodes[qubo_nodes[:,0]==i,2][0]ifiinqubo_nodes[:,0]else0.)]foriinnp.arange(np.concatenate((qubo_nodes,qubo_couplers))[:,[0,1]].max()+1)])# to make sure every (i,i) occurs in the qubo in increasing order such that the variable order in BinaryQuadraticModel is consistent (see locate wrongenergies-* github issue)
maxcouplers=len(qubo_couplers)## POSSIBLE INPUT if len(sys.argv) <= 2 else int(sys.argv[2])
ifnot'train'indata_key:
raiseException(f'careful: datakey={data_key} => youre trying to train on a validation / test set!')
couplerslist=[min(7500,maxcouplers)]# The 7500 here is more or less arbitrary and may need to be adjusted. Just to be sure that the number of couplers is not larger than the number of physical couplers (EmbeddingComposite does not seem to check for this)
#NOTE left out: pickle.dump(response, open(pathsub+'response.pkl','wb')) # contains full response incl. response.record etc; can be loaded with pickle.load(open('response.pkl','rb'))
samples=np.array([''.join(map(str,sample))forsampleinresponse.record['sample']])# NOTE: it would be safer to use the labeling from record.data() for the qubit variable order
unique_samples,unique_idx,unique_counts=np.unique(samples,return_index=True,return_counts=True)# unfortunately, num_occurrences seems not to be added up after unembedding
unique_records=response.record[unique_idx]
result=rfn.merge_arrays((unique_samples,unique_records['energy'],unique_counts,unique_records['chain_break_fraction']))# see comment on chain_strength above
result=result[np.argsort(result['f1'])]
np.savetxt(pathsub_ext+'result.dat',result[:MAXRESULTS],fmt='%s',delimiter='\t',header='\t'.join(response.record.dtype.names),comments='')# load with np.genfromtxt(..., dtype=['<U2000',float,int,float], names=True, encoding=None)
ifall(np.logical_or(np.isclose(alphas[i],0),np.isclose(alphas[i],C)))ornp.isclose(np.sum(alphas[i]*(C-alphas[i])),0):#remove cases where no support vectors are found (all alpha=0 or only slack variables all alpha=0 or alpha=C) -> numerical recipes Eq. 16.5.24
print(f'Deleting alphas[{i}].')
delalphas[i]
alphas=np.array(alphas)
ifmax_alphas==0ormax_alphas>len(alphas):
nalphas=len(alphas)
else:
nalphas=max_alphas
assertlen(data)==alphas.shape[1],"alphas do not seem to be for the right data set?)"
trainacc_all=np.zeros([nalphas])
trainauroc_all=np.zeros([nalphas])
trainauprc_all=np.zeros([nalphas])
testacc_all=np.zeros([nalphas])
testauroc_all=np.zeros([nalphas])
testauprc_all=np.zeros([nalphas])
alphas_avg=np.zeros(len(alphas[0]))
energies2=np.zeros([nalphas])
foriinrange(nalphas):
alphas_n=alphas[i]
alphas_avg+=alphas_n
b=eval_offset_avg(alphas_n,data,label,gamma,C)# NOTE: this is NAN if no support vectors were found, see TODO file