diff options
Diffstat (limited to 'src/parameters')
-rw-r--r-- | src/parameters/learn.cpp | 282 | ||||
-rw-r--r-- | src/parameters/parameters.cpp | 462 | ||||
-rw-r--r-- | src/parameters/parameters.h | 123 | ||||
-rw-r--r-- | src/parameters/persistent.cpp | 202 |
4 files changed, 1069 insertions, 0 deletions
diff --git a/src/parameters/learn.cpp b/src/parameters/learn.cpp new file mode 100644 index 0000000..aaef5a2 --- /dev/null +++ b/src/parameters/learn.cpp @@ -0,0 +1,282 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * This program 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 this program in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "parameters.h" +#include "../measurement/measurement.h" + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +extern int debug_learning; + +double calculate_params(struct parameter_bundle *params) +{ + unsigned int i; + + params->score = 0; + + + for (i = 0; i < past_results.size(); i++) + compute_bundle(params, past_results[i]); + + return params->score; +} + + +/* + * gradual linear convergence of non-independent variables works better if once in a while + * you make a wrong move.... + */ +static int random_disturb(int retry_left) +{ + if (retry_left < 10) + return 0; + + if ( (rand() % 500) == 7) + return 1; + return 0; +} + +static int try_zero(double value) +{ + if (value > 0.01) + if ( (rand() % 100) == 1) + return 1; + + if ( (rand() % 5) == 1) + return 1; + return 0; +} + +static unsigned int previous_measurements; + +static void weed_empties(struct parameter_bundle *best_so_far) +{ + double best_score; + unsigned int i; + + best_score = best_so_far->score; + + + for (i = 0; i < best_so_far->parameters.size(); i++) { + double orgvalue; + + orgvalue = best_so_far->parameters[i]; + + + best_so_far->parameters[i] = 0.0; + + calculate_params(best_so_far); + if (best_so_far->score > best_score) { + best_so_far->parameters[i] = orgvalue; + } else { + best_score = best_so_far->score; + } + + } + calculate_params(best_so_far); + +} + +/* leaks like a sieve */ +void learn_parameters(int iterations, int do_base_power) +{ + struct parameter_bundle *best_so_far; + double best_score = 10000000000000000.0; + int retry = iterations; + int prevparam = -1; + int locked = 0; + static unsigned int bpi = 0; + unsigned int i; + time_t start; + + /* don't start fitting anything until we have at least 1 more measurement than we have parameters */ + if (past_results.size() <= all_parameters.parameters.size()) + return; + + + +// if (past_results.size() == previous_measurements) +// return; + + precompute_valid(); + + + previous_measurements = past_results.size(); + + double delta = 0.50; + + best_so_far = &all_parameters; + + if (!bpi) + bpi = get_param_index("base power"); + + calculate_params(best_so_far); + best_score = best_so_far->score; + + delta = 0.001 / pow(0.8, iterations / 2.0); + if (iterations < 25) + delta = 0.001 / pow(0.5, iterations / 2.0); + + if (delta > 0.2) + delta = 0.2; + + if (1.0 * best_score / past_results.size() < 4 && delta > 0.05) + delta = 0.05; + + if (debug_learning) + printf("Delta starts at %5.3f\n", delta); + + if (best_so_far->parameters[bpi] > min_power * 0.9) + best_so_far->parameters[bpi] = min_power * 0.9; + + /* We want to give up a little of base power, to give other parameters room to change; + base power is the end post for everything after all + */ + if (do_base_power && !debug_learning) + best_so_far->parameters[bpi] = best_so_far->parameters[bpi] * 0.9998; + + start = time(NULL); + + while (retry--) { + int changed = 0; + int bestparam; + double newvalue = 0; + double orgscore; + double weight; + + bestparam = -1; + + if (time(NULL) - start > 1 && !debug_learning) + retry = 0; + + calculate_params(best_so_far); + orgscore = best_score = best_so_far->score; + + + for (i = 1; i < best_so_far->parameters.size(); i++) { + double value, orgvalue; + + weight = delta * best_so_far->weights[i]; + + orgvalue = value = best_so_far->parameters[i]; + if (value <= 0.001) { + value = 0.1; + } else + value = value * (1 + weight); + + if (i == bpi && value > min_power) + value = min_power; + + if (i == bpi && orgvalue > min_power) + orgvalue = min_power; + + if (value > 5000) + value = 5000; + +// printf("Trying %s %4.2f -> %4.2f\n", param.c_str(), best_so_far->parameters[param], value); + best_so_far->parameters[i] = value; + + calculate_params(best_so_far); + if (best_so_far->score < best_score || random_disturb(retry)) { + best_score = best_so_far->score; + newvalue = value; + bestparam = i; + changed++; + } + + value = orgvalue * 1 / (1 + weight); + + if (value < 0.0001) + value = 0.0; + + if (try_zero(value)) + value = 0.0; + + + if (value > 5000) + value = 5000; + + +// printf("Trying %s %4.2f -> %4.2f\n", param.c_str(), orgvalue, value); + + if (orgvalue != value) { + best_so_far->parameters[i] = value; + + calculate_params(best_so_far); + + if (best_so_far->score + 0.00001 < best_score || (random_disturb(retry) && value > 0.0)) { + best_score = best_so_far->score; + newvalue = value; + bestparam = i; + changed++; + } + } + best_so_far->parameters[i] = orgvalue; + + } + if (!changed) { + double mult; + + if (!locked) { + mult = 0.8; + if (iterations < 25) + mult = 0.5; + delta = delta * mult; + } + locked = 0; + prevparam = -1; + } else { + if (debug_learning) { + printf("Retry is %i \n", retry); + printf("delta is %5.4f\n", delta); + printf("Best parameter is %i \n", bestparam); + printf("Changing score from %4.3f to %4.3f\n", orgscore, best_score); + printf("Changing value from %4.3f to %4.3f\n", best_so_far->parameters[bestparam], newvalue); + } + best_so_far->parameters[bestparam] = newvalue; + if (prevparam == bestparam) + delta = delta * 1.1; + prevparam = bestparam; + locked = 1; + } + + if (delta < 0.001 && !locked) + break; + + if (retry % 50 == 49) + weed_empties(best_so_far); + } + + + /* now we weed out all parameters that don't have value */ + if (iterations > 50) + weed_empties(best_so_far); + + if (debug_learning) + printf("Final score %4.2f (%i points)\n", best_so_far->score / past_results.size(), (int)past_results.size()); +// dump_parameter_bundle(best_so_far); +// dump_past_results(); +} diff --git a/src/parameters/parameters.cpp b/src/parameters/parameters.cpp new file mode 100644 index 0000000..38e1752 --- /dev/null +++ b/src/parameters/parameters.cpp @@ -0,0 +1,462 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * This program 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 this program in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include "parameters.h" +#include "../measurement/measurement.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <vector> +#include <unistd.h> +#include <limits.h> + + +struct parameter_bundle all_parameters; +struct result_bundle all_results; + +vector <struct result_bundle *> past_results; + +map <string, int> param_index; +static int maxindex = 1; +map <string, int> result_index; +static int maxresindex = 1; + +int get_param_index(const char *name) +{ + std::map<string, int>::iterator it; + int index = 0; + + it = param_index.find(name); + if (it == param_index.end()) { + param_index[name] = ++maxindex; + index = maxindex; + } else + index = it->second; + + if (index == 0) + printf("OH BLA\n"); + return index; +} + +int get_result_index(const char *name) +{ + std::map<string, int>::iterator it; + int index = 0; + + it = result_index.find(name); + if (it == result_index.end()) { + result_index[name] = ++maxresindex; + index = maxresindex; + } else + index = it->second; + + return index; +} + + +void register_parameter(const char *name, double default_value, double weight) +{ + int index; + + index = get_param_index(name); + + if (index >= (int)all_parameters.parameters.size()) { + all_parameters.parameters.resize(index+1, 0.0); + all_parameters.weights.resize(index+1, 1.0); + } + + if (all_parameters.parameters[index] <= 0.0001) + all_parameters.parameters[index] = default_value; + + all_parameters.weights[index] = weight; +} + +void set_parameter_value(const char *name, double value, struct parameter_bundle *bundle) +{ + int index; + + index = get_param_index(name); + + if (index >= (int)bundle->parameters.size()) { + bundle->parameters.resize(index+1, 0.0); + bundle->weights.resize(index+1, 1.0); + } + + bundle->parameters[index] = value; +} + +double get_parameter_value(const char *name, struct parameter_bundle *the_bundle) +{ + unsigned int index; + index = get_param_index(name); + return get_parameter_value(index, the_bundle); +} + +double get_parameter_value(unsigned int index, struct parameter_bundle *the_bundle) +{ + if (index >= the_bundle->parameters.size()) { + fprintf(stderr, "BUG: requesting unregistered parameter %d\n", index); + return 0; + } + return the_bundle->parameters[index]; +} + +double get_parameter_weight(int index, struct parameter_bundle *the_bundle) +{ + return the_bundle->weights[index]; +} + +double get_result_value(const char *name, struct result_bundle *the_bundle) +{ + return get_result_value(get_result_index(name), the_bundle); +} + +void set_result_value(const char *name, double value, struct result_bundle *the_bundle) +{ + unsigned int index = get_result_index(name); + if (index >= the_bundle->utilization.size()) + the_bundle->utilization.resize(index+1); + the_bundle->utilization[index] = value; +} + +void set_result_value(unsigned int index, double value, struct result_bundle *the_bundle) +{ + if (index >= the_bundle->utilization.size()) + the_bundle->utilization.resize(index+1); + the_bundle->utilization[index] = value; +} + +double get_result_value(int index, struct result_bundle *the_bundle) +{ + if (!the_bundle) + return 0; + if (index >= (int) the_bundle->utilization.size()) + return 0; + return the_bundle->utilization[index]; +} + + +int result_device_exists(const char *name) +{ + unsigned int i; + for (i = 0; i < all_devices.size(); i++) { + if (strcmp(all_devices[i]->device_name(), name) == 0) + return 1; + } + return 0; +} + +void report_utilization(const char *name, double value, struct result_bundle *bundle) +{ + set_result_value(name, value, bundle); +} +void report_utilization(int index, double value, struct result_bundle *bundle) +{ + set_result_value(index, value, bundle); +} + + + +double compute_bundle(struct parameter_bundle *parameters, struct result_bundle *results) +{ + double power = 0; + unsigned int i; + + static int bpi = 0; + + if (!bpi) + bpi = get_param_index("base power"); + + for (i = 0; i < all_devices.size(); i++) + power += all_devices[i]->power_usage(results, parameters); + + parameters->actual_power = results->power; + parameters->guessed_power = power; + /* scale the squared error by the actual power so that non-idle data points weigh heavier */ + parameters->score += results->power * (power - results->power) * (power - results->power); + parameters->parameters[bpi] = power; + return power; +} + +static int precomputed_valid = 0; +void precompute_valid(void) +{ + unsigned int i; + + + for (i = 0; i < all_devices.size(); i++) { + all_devices[i]->cached_valid = all_devices[i]->power_valid(); + } + precomputed_valid = 1; +} + +double bundle_power(struct parameter_bundle *parameters, struct result_bundle *results) +{ + double power = 0; + unsigned int i; + static int bpi = 0; + + if (!bpi) + bpi = get_param_index("base power"); + + if (!precomputed_valid) + precompute_valid(); + + + power = parameters->parameters[bpi]; + + for (i = 0; i < all_devices.size(); i++) { + + if (all_devices[i]->cached_valid) + power += all_devices[i]->power_usage(results, parameters); + } + + return power; +} + + +void dump_parameter_bundle(struct parameter_bundle *para) +{ + map<string, int>::iterator it; + int index; + + printf("\n\n"); + printf("Parameter state \n"); + printf("----------------------------------\n"); + printf("Value\t\tName\n"); + for (it = param_index.begin(); it != param_index.end(); it++) { + index = it->second; + printf("%5.2f\t\t%s (%i)\n", para->parameters[index], it->first.c_str(), index); + } + + printf("\n"); + printf("Score: %5.1f (%5.1f)\n", sqrt(para->score / (0.001 + past_results.size()) / average_power()), para->score); + printf("Guess: %5.1f\n", para->guessed_power); + printf("Actual: %5.1f\n", para->actual_power); + + printf("----------------------------------\n"); +} + +void dump_result_bundle(struct result_bundle *res) +{ + map<string, int>::iterator it; + unsigned int index; + + printf("\n\n"); + printf("Utilisation state \n"); + printf("----------------------------------\n"); + printf("Value\t\tName\n"); + for (it = result_index.begin(); it != result_index.end(); it++) { + index = get_result_index(it->first.c_str()); + printf("%5.2f%%\t\t%s(%i)\n", res->utilization[index], it->first.c_str(), index); + } + + printf("\n"); + printf("Power: %5.1f\n", res->power); + + printf("----------------------------------\n"); +} + +struct result_bundle * clone_results(struct result_bundle *bundle) +{ + struct result_bundle *b2; + map<string, double>::iterator it; + unsigned int i; + + b2 = new struct result_bundle; + + if (!b2) + return NULL; + + b2->power = bundle->power; + b2->utilization.resize(bundle->utilization.size()); + + for (i = 0; i < bundle->utilization.size(); i++) { + b2->utilization[i] = bundle->utilization[i]; + } + + return b2; +} + + +struct parameter_bundle * clone_parameters(struct parameter_bundle *bundle) +{ + struct parameter_bundle *b2; + unsigned int i; + + b2 = new struct parameter_bundle; + + if (!b2) + return NULL; + + b2->score = 0; + b2->guessed_power = 0; + b2->actual_power = bundle->actual_power; + b2->parameters.resize(bundle->parameters.size()); + for (i = 0; i < bundle->parameters.size(); i++) { + b2->parameters[i] = bundle->parameters[i]; + } + + return b2; +} + + +void store_results(double duration) +{ + if (duration < 5) + return; + global_power(); + if (all_results.power > 0.01) { + unsigned int overflow_index; + overflow_index = 50 + (rand() % MAX_KEEP); + if (past_results.size() >= MAX_PARAM) { + /* memory leak, must free old one first */ + past_results[overflow_index] = clone_results(&all_results); + } else { + past_results.push_back(clone_results(&all_results)); + } + if ((past_results.size() % 10) == 0) + save_all_results("saved_results.powertop"); + } + +} + + + +void dump_past_results(void) +{ + unsigned int j; + unsigned int i; + struct result_bundle *result; + + for (j = 0; j < past_results.size(); j+=10) { + printf("Est "); + for (i = j; i < past_results.size() && i < j + 10; i++) { + result = past_results[i]; + printf("%6.2f ", bundle_power(&all_parameters, result)); + } + printf("\n"); + printf("Actual "); + for (i = j; i < past_results.size() && i < j + 10; i++) { + result = past_results[i]; + printf("%6.2f ", result->power); + } + printf("\n\n"); + } +} + +double average_power(void) +{ + double sum = 0.0; + unsigned int i; + for (i = 0; i < past_results.size(); i++) + sum += past_results[i]->power; + + if (past_results.size()) + sum = sum / past_results.size() + 0.0001; + else + sum = 0.0001; + return sum; +} + +int utilization_power_valid(const char *u) +{ + unsigned int i; + unsigned int index; + double first_value; + + index = get_result_index(u); + if (index <= 0) + return 0; + + first_value = past_results[0]->utilization[index]; + for (i = 1; i < past_results.size(); i++) { + if (get_result_value(index, past_results[i]) < first_value - 0.0001) + return 1; + if (get_result_value(index, past_results[i]) > first_value + 0.0001) + return 1; + } + + return 0; +} + +int utilization_power_valid(int index) +{ + unsigned int i; + double first_value; + + if (index <= 0) + return 0; + + if (past_results.size() == 0) + return 0; + + if (index >= (int)past_results[0]->utilization.size()) + return 0; + first_value = past_results[0]->utilization[index]; + for (i = 1; i < past_results.size(); i++) { + if (get_result_value(index, past_results[i]) < first_value - 0.0001) + return 1; + if (get_result_value(index, past_results[i]) > first_value + 0.0001) + return 1; + } + + return 0; +} + + +/* force power data to be valid to the rest of the system */ +int global_power_override = 0; +int global_run_times=0; +/* + * only report power numbers once we have 3* more measurements than + * we have parameters; anything less and our model fit is highly suspect + */ +int global_power_valid(void) +{ + if (past_results.size() > 3 * all_parameters.parameters.size()) + return 1; + + if (past_results.size() > 0 && global_run_times < 1){ + printf("To show power estimates do %ld measurement(s) connected to battery only\n", + (3 * all_parameters.parameters.size()) - past_results.size()); + global_run_times += 1; + } + + return global_power_override; +} + +/* find the directory to store powertop results/parameters based on distribution*/ +char* get_param_directory(const char *filename) +{ + static char tempfilename[PATH_MAX]; + + if (access("/var/cache/powertop", W_OK ) == 0) + snprintf(tempfilename, sizeof(tempfilename), "/var/cache/powertop/%s", filename); + if (access("/data/local/powertop", W_OK ) == 0) + snprintf(tempfilename, sizeof(tempfilename), "/data/local/powertop/%s", filename); + + return tempfilename; +}; diff --git a/src/parameters/parameters.h b/src/parameters/parameters.h new file mode 100644 index 0000000..1781a0e --- /dev/null +++ b/src/parameters/parameters.h @@ -0,0 +1,123 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * This program 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 this program in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#ifndef __INCLUDE_GUARD_PARAMETERS_H_ +#define __INCLUDE_GUARD_PARAMETERS_H_ + + +#include <map> +#include <vector> +#include <string> + +#include "string.h" +#include "../devices/device.h" +#include "../lib.h" + +using namespace std; + +#define MAX_KEEP 700 +#define MAX_PARAM 750 + + +struct parameter_bundle +{ + double score; + double guessed_power; + double actual_power; + + vector<double> parameters; + vector<double> weights; +}; + +extern struct parameter_bundle all_parameters; +extern map <string, int> param_index; +extern map <string, int> result_index; + +extern int get_param_index(const char *param); +extern int get_result_index(const char *param); + + +extern void register_parameter(const char *name, double default_value = 0.00, double weight = 1.0); +extern double get_parameter_value(const char *name, struct parameter_bundle *bundle = &all_parameters); +extern double get_parameter_value(unsigned int index, struct parameter_bundle *bundle = &all_parameters); +extern void set_parameter_value(const char *name, double value, struct parameter_bundle *bundle = &all_parameters); + + +struct result_bundle +{ + double joules; + double power; + vector <double> utilization; /* device name, device utilization %age */ +}; + +extern struct result_bundle all_results; +extern vector <struct result_bundle *> past_results; + +extern double get_result_value(const char *name, struct result_bundle *bundle = &all_results); +extern double get_result_value(int index, struct result_bundle *bundle = &all_results); + +extern void set_result_value(const char *name, double value, struct result_bundle *bundle = &all_results); + + +extern int result_device_exists(const char *name); + +extern void report_utilization(const char *name, double value, struct result_bundle *bundle = &all_results); +extern void report_utilization(int index, double value, struct result_bundle *bundle = &all_results); + + +extern void precompute_valid(void); + +extern double compute_bundle(struct parameter_bundle *parameters = &all_parameters, struct result_bundle *results = &all_results); + + +void dump_parameter_bundle(struct parameter_bundle *patameters = &all_parameters); +void dump_result_bundle(struct result_bundle *res = &all_results); + +extern struct result_bundle * clone_results(struct result_bundle *bundle); +extern struct parameter_bundle * clone_parameters(struct parameter_bundle *bundle); + +extern void store_results(double duration); +extern void learn_parameters(int iterations, int do_base_power); +extern char *get_param_directory(const char *filename); +extern void save_all_results(const char *filename = "saved_results.powertop"); +extern void close_results(void); +extern void load_results(const char *filename); +extern void save_parameters(const char *filename); +extern void load_parameters(const char *filename); + +extern void dump_past_results(void); +extern double bundle_power(struct parameter_bundle *parameters, struct result_bundle *results); + +extern double average_power(void); + +extern int utilization_power_valid(const char *u); +extern int utilization_power_valid(int index); +extern double calculate_params(struct parameter_bundle *params = &all_parameters); +int global_power_valid(void); + + +extern int global_power_override; + + +#endif diff --git a/src/parameters/persistent.cpp b/src/parameters/persistent.cpp new file mode 100644 index 0000000..0711b4d --- /dev/null +++ b/src/parameters/persistent.cpp @@ -0,0 +1,202 @@ +/* + * Copyright 2010, Intel Corporation + * + * This file is part of PowerTOP + * + * This program file 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; version 2 of the License. + * + * This program 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 this program in a file named COPYING; if not, write to the + * Free Software Foundation, Inc, + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * or just google for it. + * + * Authors: + * Arjan van de Ven <arjan@linux.intel.com> + */ +#include <iostream> +#include <fstream> +#include <iomanip> +#include <stdlib.h> + +#include "parameters.h" +#include "../measurement/measurement.h" + +using namespace std; + +void save_all_results(const char *filename) +{ + ofstream file; + unsigned int i; + struct result_bundle *bundle; + char* pathname; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::out); + if (!file) { + cout << _("Cannot save to file") << " " << pathname << "\n"; + return; + } + for (i = 0; i < past_results.size(); i++) { + bundle = past_results[i]; + map<string, int>::iterator it; + file << setiosflags(ios::fixed) << setprecision(5) << bundle->power << "\n"; + + for (it = result_index.begin(); it != result_index.end(); it++) { + file << it->first << "\t" << setprecision(5) << get_result_value(it->second, bundle) << "\n"; + } + file << ":\n"; + } + + file.close(); + +} + +void close_results() +{ + for (unsigned int i = 0; i < past_results.size(); i++) { + delete past_results[i]; + } + + past_results.clear(); + return; +} + +void load_results(const char *filename) +{ + ifstream file; + char line[4096]; + char *c1; + struct result_bundle *bundle; + int first = 1; + unsigned int count = 0; + char* pathname; + int bundle_saved = 0; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::in); + if (!file) { + cout << _("Cannot load from file") << " " << pathname << "\n"; + return; + } + + bundle = new struct result_bundle; + + while (file) { + double d; + if (first) { + file.getline(line, 4096); + if (strlen(line)>0) { + sscanf(line, "%lf", &bundle->power); + if (bundle->power < min_power) + min_power = bundle->power; + } + first = 0; + continue; + } + file.getline(line, 4096); + if (strlen(line) < 3) { + int overflow_index; + + bundle_saved = 1; + overflow_index = 50 + (rand() % MAX_KEEP); + if (past_results.size() >= MAX_PARAM) { + /* memory leak, must free old one first */ + past_results[overflow_index] = bundle; + } else { + past_results.push_back(bundle); + } + bundle = new struct result_bundle; + first = 1; + count++; + continue; + } + c1 = strchr(line, '\t'); + if (!c1) + continue; + *c1 = 0; + c1++; + sscanf(c1, "%lf", &d); + set_result_value(line, d, bundle); + } + + if (bundle_saved == 0) + delete bundle; + + file.close(); + // '%i" is for count, do not translate + fprintf(stderr, _("Loaded %i prior measurements\n"), count); +} + +void save_parameters(const char *filename) +{ + ofstream file; + char* pathname; + +// printf("result size is %i, #parameters is %i \n", (int)past_results.size(), (int)all_parameters.parameters.size()); + + if (!global_power_valid()) + return; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::out); + if (!file) { + cout << _("Cannot save to file") << " " << pathname << "\n"; + return; + } + + map<string, int>::iterator it; + + for (it = param_index.begin(); it != param_index.end(); it++) { + int index; + index = it->second; + file << it->first << "\t" << setprecision(9) << all_parameters.parameters[index] << "\n"; + } + file.close(); +} + +void load_parameters(const char *filename) +{ + ifstream file; + char line[4096]; + char *c1; + char* pathname; + + pathname = get_param_directory(filename); + + file.open(pathname, ios::in); + if (!file) { + cout << _("Cannot load from file") << " " << pathname << "\n"; + cout << _("File will be loaded after taking minimum number of measurement(s) with battery only \n"); + return; + } + + while (file) { + double d; + memset(line, 0, 4096); + file.getline(line, 4095); + + c1 = strchr(line, '\t'); + if (!c1) + continue; + *c1 = 0; + c1++; + sscanf(c1, "%lf", &d); + + + set_parameter_value(line, d); + } + + file.close(); +} |