void test_machine_encode_plugboard() { // Encode few letters and log the output. machine m; m.rotors = std::vector<rotor>({ rotor(w1), rotor(w2), rotor(w3) }); m.plugs.set('A', 'D'); m.plugs.set('O', 'L'); std::string s = m.encode_string("AHOJ"); std::cout << "\n\nEntire encoded message: " << s; std::cout << "\n"; }
void test_machine_encode_decode() { // Encode few letters and log the output. machine m, n; m.rotors = std::vector<rotor>({ rotor(w1), rotor(w2), rotor(w3) }); m.reflector = rotor(w_ra); m.plugs.set('A', 'D'); m.plugs.set('O', 'L'); n.rotors = std::vector<rotor>({ rotor(w1), rotor(w2), rotor(w3) }); n.reflector = rotor(w_ra); n.plugs.set('A', 'D'); n.plugs.set('O', 'L'); for (int i = 0; i < 100; i++) { std::string s = m.encode_string("AHOJ"); std::cout << "\nEntire encoded message: " << s; std::cout << "\nDecoding now..."; std::string t = n.encode_string(s); std::cout << "\nEntire decoded message: " << t << "\n"; } std::cout << "\n"; }
/// Update rotation of camera /// @param cam camera /// @param rotation amount camera is rotated void FPSCameraTemplate::UpdateRotation(const SceneObject* scene_object, CameraPtr cam, Vector3f new_rotation) { Vector3f rotor(new_rotation - scene_object->getRotation()); Vector3f pos(scene_object->getPosition()); Vector3f t(cam->getTarget()); t.rotateXYBy(rotor.Z, pos); cam->setTarget(t); }
Encode::Encode(char** rotorFiles, const char* plugboardFile, int numOfRotorFiles){ this->numOfRotorFiles = numOfRotorFiles; // Create thw rotors for(int i = 0; i < numOfRotorFiles; ++i){ std::shared_ptr<Rotor> rotor (new Rotor(rotorFiles[i])); rotors.push_back(rotor); } // Create the plugboard plugboard = new Plugboard(plugboardFile); // Create the reflector reflector = new Reflector(); }
SolutionInfo Alignment::align(bool n) { // create initial solution SolutionInfo si; si.volume = -1000.0; si.iterations = 0; si.center1 = _refCenter; si.center2 = _dbCenter; si.rotation1 = _refRotMat; si.rotation2 = _dbRotMat; // scaling of the exclusion spheres double scale(1.0); if (_nbrExcl != 0) { scale /= _nbrExcl; } // try 4 different start orientations for (unsigned int _call(0); _call < 4; ++_call ) { // create initial rotation quaternion SiMath::Vector rotor(4,0.0); rotor[_call] = 1.0; double volume(0.0), oldVolume(-999.99), v(0.0); SiMath::Vector dG(4,0.0); // gradient update SiMath::Matrix hessian(4,4,0.0), dH(4,4,0.0); // hessian and hessian update unsigned int ii(0); for ( ; ii < 100; ++ii) { // compute gradient of volume _grad = 0.0; volume = 0.0; hessian = 0.0; for (unsigned int i(0); i < _refMap.size(); ++i) { // compute the volume overlap of the two pharmacophore points SiMath::Vector Aq(4,0.0); SiMath::Matrix * AkA = _AkA[i]; Aq[0] = (*AkA)[0][0] * rotor[0] + (*AkA)[0][1] * rotor[1] + (*AkA)[0][2] * rotor[2] + (*AkA)[0][3] * rotor[3]; Aq[1] = (*AkA)[1][0] * rotor[0] + (*AkA)[1][1] * rotor[1] + (*AkA)[1][2] * rotor[2] + (*AkA)[1][3] * rotor[3]; Aq[2] = (*AkA)[2][0] * rotor[0] + (*AkA)[2][1] * rotor[1] + (*AkA)[2][2] * rotor[2] + (*AkA)[2][3] * rotor[3]; Aq[3] = (*AkA)[3][0] * rotor[0] + (*AkA)[3][1] * rotor[1] + (*AkA)[3][2] * rotor[2] + (*AkA)[3][3] * rotor[3]; double qAq = Aq[0] * rotor[0] + Aq[1] * rotor[1] + Aq[2] * rotor[2] +Aq[3] * rotor[3]; v = GCI2 * pow(PI/(_refMap[i].alpha+_dbMap[i].alpha),1.5) * exp(-qAq); double c(1.0); // add normal if AROM-AROM // in this case the absolute value of the angle is needed if (n && (_refMap[i].func == AROM) && (_dbMap[i].func == AROM) && (_refMap[i].hasNormal) && (_dbMap[i].hasNormal)) { // for aromatic rings only the planar directions count // therefore the absolute value of the cosine is taken c = _normalContribution(_refMap[i].normal, _dbMap[i].normal, rotor); // update based on the sign of the cosine if (c < 0) { c *= -1.0; _dCdq *= -1.0; _d2Cdq2 *= -1.0; } for (unsigned int hi(0); hi < 4; hi++) { _grad[hi] += v * ( _dCdq[hi] - 2.0 * c * Aq[hi] ); for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += v * (_d2Cdq2[hi][hj] - 2.0 * _dCdq[hi]*Aq[hj] + 2.0 * c * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj])); } } v *= c; } else if (n && ((_refMap[i].func == HACC) || (_refMap[i].func == HDON) || (_refMap[i].func == HYBH)) && ((_dbMap[i].func == HYBH) || (_dbMap[i].func == HACC) || (_dbMap[i].func == HDON)) && (_refMap[i].hasNormal) && (_dbMap[i].hasNormal)) { // hydrogen donors and acceptor also have a direction // in this case opposite directions have negative impact c = _normalContribution(_refMap[i].normal, _dbMap[i].normal, rotor); for (unsigned int hi(0); hi < 4; hi++) { _grad[hi] += v * ( _dCdq[hi] - 2.0 * c * Aq[hi] ); for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += v * (_d2Cdq2[hi][hj] - 2.0 * _dCdq[hi]*Aq[hj] + 2.0 * c * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj])); } } v *= c; } else if (_refMap[i].func == EXCL) { // scale volume overlap of exclusion sphere with a negative scaling factor // => exclusion spheres have a negative impact v *= -scale; // update gradient and hessian directions for (unsigned int hi=0; hi < 4; hi++) { _grad[hi] -= 2.0 * v * Aq[hi]; for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += 2.0 * v * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj]); } } } else { // update gradient and hessian directions for (unsigned int hi(0); hi < 4; hi++) { _grad[hi] -= 2.0 * v * Aq[hi]; for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += 2.0 * v * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj]); } } } volume += v; } // stop iterations if the increase in volume overlap is too small (gradient ascent) // or if the volume is not defined if (std::isnan(volume) || (volume - oldVolume < 1e-5)) { break; } // reset old volume oldVolume = volume; inverseHessian(hessian); // update gradient based on inverse hessian _grad = rowProduct(hessian,_grad); // small scaling of the gradient _grad *= 0.9; // update rotor based on gradient information rotor += _grad; // normalise rotor such that it has unit norm normalise(rotor); } // save result in info structure if (oldVolume > si.volume) { si.rotor = rotor; si.volume = oldVolume; si.iterations = ii; } } return si; }