VariableVector increment_weight_vector(const VariableVector& weights, const VariableVector& scaled_gradient) { VariableVector empty; if (weights.size() != scaled_gradient.size()) { return empty; } VariableVector incremented; string partial_name, weight_name; double scaled_partial, weight_val; for (VariableVector::const_iterator it = scaled_gradient.begin(); it != scaled_gradient.end(); ++it) { partial_name = it->first; scaled_partial = it->second; weight_name = partial_name_to_weight_name(partial_name); if (weights.count(weight_name) == 0) { return empty; } weight_val = weights.at(weight_name); incremented.insert(make_pair(weight_name, weight_val + scaled_partial)); } return incremented; }
VariableVector add_variable_vectors(const VariableVector& vec1, const VariableVector& vec2) { VariableVector empty; VariableVector sum; string var_name; double component_sum; // if the vectors are of different sizes, return empty if (vec1.size() != vec2.size()) return empty; for (VariableVector::const_iterator it1 = vec1.begin(); it1 != vec1.end(); ++it1) { var_name = it1->first; // if this variable is in both vectors, add the values if (vec2.count(var_name) != 0) { component_sum = it1->second + vec2.at(var_name); sum.insert(make_pair(var_name, component_sum)); } // if this variable is only in vec1, return empty else { return empty; } } // if we reach this point, every variable in vec1 is also in vec2 // since both vectors are of the same size, it is safe to return return sum; }
double distance_between_variable_vectors(const VariableVector& vec1, const VariableVector& vec2) { // Both vectors must have the same dimension if (vec1.size() != vec2.size()) { return -1; } double square_distance = 0; string var_name; double val1, val2; for (VariableVector::const_iterator it = vec1.begin(); it != vec1.end(); ++it) { var_name = it->first; // Both vectors must have exactly the same variables if (vec2.count(var_name) == 0) { return -1; } val1 = vec1.at(var_name); val2 = vec2.at(var_name); square_distance += pow((val1 - val2), 2); } return pow(square_distance, 0.5); }
VariableVector avg_gradient(const string& gcp_filename, const vector<string>& partial_names, const VariableVector& weights, const vector<pair<VariableVector, VariableVector> >& training_data) { VariableVector empty; // check for trivial errors if (partial_names.size() != weights.size()) return empty; // initialize the sum_of_partials_vector VariableVector sum_of_partials = vector_of_zeros(partial_names); VariableVector *partials; int find_partials_success = 0; for (vector<pair<VariableVector, VariableVector> >::const_iterator datum = training_data.begin(); datum != training_data.end(); ++datum) { partials = new VariableVector(); VariableVector inputs = datum->first; VariableVector outputs = datum->second; find_partials_success = find_partials(gcp_filename, partials, weights, inputs, outputs); if (find_partials_success != 0) return empty; sum_of_partials = add_variable_vectors(sum_of_partials, *partials); if (sum_of_partials.size() == 0) return empty; delete partials; } return component_wise_div(sum_of_partials, training_data.size()); }
bool approx_zero(const VariableVector& vec, const vector<string>& partial_names) { if (vec.size() != partial_names.size()) { return false; } VariableVector zeros = vector_of_zeros(partial_names); double pyth_dist = distance_between_variable_vectors(vec, zeros); if (pyth_dist == -1) { return false; } return (pyth_dist <= GRADIENT_PRECISION); }
VariableVector calculate_weights(const string& gcp_filename, const vector<string>& weight_names, const vector<string>& partial_names, const vector<pair<VariableVector, VariableVector> >& training_data) { VariableVector weights = initial_weight_guess(weight_names); VariableVector gradient = avg_gradient(gcp_filename, partial_names, weights, training_data); int num_iterations = 0; cout << "Calculating weights for GCP " << gcp_filename << "..." << endl; while (!approx_zero(gradient, partial_names) && num_iterations < MAX_NUM_ITERATIONS) { weights = increment_weight_vector(weights, scale_variable_vector(gradient, -1 * LEARNING_RATE)); gradient = avg_gradient(gcp_filename, partial_names, weights, training_data); num_iterations++; if (gradient.size() == 0) break; } return weights; }
TEST_F(AnalysisFixture, Problem_UpdateMeasure_MeasureGroups) { // open up example measure openstudio::path measuresPath = resourcesPath() / toPath("/utilities/BCL/Measures/v2"); openstudio::path dir = measuresPath / toPath("SetWindowToWallRatioByFacade"); ASSERT_TRUE(BCLMeasure::load(dir)); BCLMeasure measure1 = BCLMeasure::load(dir).get(); openstudio::path tempDir1 = measuresPath / toPath(toString(createUUID())); openstudio::path tempDir2 = measuresPath / toPath(toString(createUUID())); { // create multiple BCLMeasures BCLMeasure measure1_1 = measure1.clone(tempDir1).get(); measure1_1.setDescription("Window to wall ratio by wwr and offset."); measure1_1.save(); EXPECT_TRUE(measure1_1.uuid() == measure1.uuid()); EXPECT_FALSE(measure1_1.versionUUID() == measure1.versionUUID()); BCLMeasure measure2 = measure1.clone(tempDir2).get(); measure2.changeUID(); measure2.incrementVersionId(); measure2.save(); EXPECT_FALSE(measure2.uuid() == measure1.uuid()); EXPECT_FALSE(measure2.versionUUID() == measure1.versionUUID()); // create args for those measures OSArgumentVector args1, args1_1, args2; args1.push_back(OSArgument::makeDoubleArgument("wwr")); args1.push_back(OSArgument::makeDoubleArgument("sillHeight")); args1_1.push_back(OSArgument::makeDoubleArgument("wwr")); args1_1.push_back(OSArgument::makeDoubleArgument("offset")); args1_1.push_back(OSArgument::makeDoubleArgument("vt")); args2.push_back(OSArgument::makeIntegerArgument("numPeople")); // create a problem that uses multiple BCLMeasures Problem problem("Problem",VariableVector(),runmanager::Workflow()); MeasureGroup dv("South WWR",MeasureVector(1u,NullMeasure())); problem.push(dv); RubyMeasure rp(measure1); rp.setArguments(args1); dv.push(rp); dv.push(rp.clone().cast<RubyMeasure>()); ASSERT_EQ(3u,dv.numMeasures(false)); rp = dv.measures(false)[2].cast<RubyMeasure>(); EXPECT_EQ(2u,rp.arguments().size()); EXPECT_TRUE(rp.hasIncompleteArguments()); dv = MeasureGroup("Occupancy",MeasureVector(1u,NullMeasure())); problem.push(dv); rp = RubyMeasure(measure2); rp.setArguments(args2); dv.push(rp); OSArgument arg = args2[0].clone(); arg.setValue(100); rp.setArgument(arg); EXPECT_EQ(1u,rp.arguments().size()); EXPECT_FALSE(rp.hasIncompleteArguments()); dv = MeasureGroup("North WWR",MeasureVector(1u,NullMeasure())); problem.push(dv); rp = RubyMeasure(measure1); rp.setArguments(args1); arg = args1[0].clone(); arg.setValue(0.32); rp.setArgument(arg); arg = args1[1].clone(); arg.setValue(1.0); rp.setArgument(arg); EXPECT_EQ(2u,rp.arguments().size()); EXPECT_FALSE(rp.hasIncompleteArguments()); dv.push(rp); EXPECT_EQ(2u,dv.numMeasures(false)); // call update problem.clearDirtyFlag(); problem.updateMeasure(measure1_1,args1_1,false); // check state VariableVector vars = castVector<Variable>(problem.variables()); ASSERT_EQ(3u,vars.size()); EXPECT_TRUE(vars[0].isDirty()); EXPECT_FALSE(vars[1].isDirty()); EXPECT_TRUE(vars[2].isDirty()); dv = vars[0].cast<MeasureGroup>(); ASSERT_EQ(3u,dv.numMeasures(false)); MeasureVector ps = dv.measures(false); EXPECT_FALSE(ps[0].isDirty()); EXPECT_TRUE(ps[1].isDirty()); rp = ps[1].cast<RubyMeasure>(); EXPECT_EQ(3u,rp.arguments().size()); EXPECT_EQ(3u,rp.incompleteArguments().size()); EXPECT_TRUE(ps[2].isDirty()); rp = ps[2].cast<RubyMeasure>(); EXPECT_EQ(3u,rp.arguments().size()); EXPECT_EQ(3u,rp.incompleteArguments().size()); dv = vars[2].cast<MeasureGroup>(); ASSERT_EQ(2u,dv.numMeasures(false)); ps = dv.measures(false); EXPECT_FALSE(ps[0].isDirty()); EXPECT_TRUE(ps[1].isDirty()); rp = ps[1].cast<RubyMeasure>(); EXPECT_EQ(3u,rp.arguments().size()); EXPECT_EQ(2u,rp.incompleteArguments().size()); } boost::filesystem::remove_all(tempDir1); boost::filesystem::remove_all(tempDir2); }
void Stepper::unregisterProcess( Process* aProcess ) { ProcessVector::iterator ip( std::find( theProcessVector.begin(), theProcessVector.end(), aProcess ) ); if( ip == theProcessVector.end() ) { THROW_EXCEPTION_INSIDE( NotFound, asString() + ": Failed to dissociate [" + aProcess->asString() + "] (no such Process is " "associated to this stepper)" ); } typedef std::set< Variable* > VariableSet; VariableSet aVarSet; Process::VariableReferenceVector const& aVarRefVector( aProcess->getVariableReferenceVector() ); std::transform( aVarRefVector.begin(), aVarRefVector.end(), inserter( aVarSet, aVarSet.begin() ), std::mem_fun_ref( &VariableReference::getVariable ) ); VariableVector aNewVector; VariableVector::size_type aReadWriteVariableOffset, aReadOnlyVariableOffset; for( VariableVector::iterator i( theVariableVector.begin() ), e( theVariableVector.begin() + theReadWriteVariableOffset ); i != e; ++i ) { VariableSet::iterator j( aVarSet.find( *i ) ); if ( j != aVarSet.end() ) aVarSet.erase( j ); else aNewVector.push_back( *i ); } aReadWriteVariableOffset = aNewVector.size(); for( VariableVector::iterator i( theVariableVector.begin() + theReadWriteVariableOffset ), e( theVariableVector.begin() + theReadOnlyVariableOffset ); i != e; ++i ) { VariableSet::iterator j( aVarSet.find( *i ) ); if ( j != aVarSet.end() ) aVarSet.erase( j ); else aNewVector.push_back( *i ); } aReadOnlyVariableOffset = aNewVector.size(); for( VariableVector::iterator i( theVariableVector.begin() + theReadOnlyVariableOffset ), e( theVariableVector.end() ); i != e; ++i ) { VariableSet::iterator j( aVarSet.find( *i ) ); if ( j != aVarSet.end() ) aVarSet.erase( j ); else aNewVector.push_back( *i ); } theVariableVector.swap( aNewVector ); theReadWriteVariableOffset = aReadWriteVariableOffset; theReadOnlyVariableOffset = aReadOnlyVariableOffset; theProcessVector.erase( ip ); }