Xpressive : much slower regex search when expression is built from sub expression - boost

Using Boost Xpressive (static expression) , I noticed that pattern searching is much slower when the expression is built from sub regexpression.
Did I miss something ? or is it inherent with the design ? Xpresive docs says
https://www.boost.org/doc/libs/1_80_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.grammars_and_nested_matches.embedding_a_regex_by_value
it is as if the regex were embedded by value; that is, a copy of the nested regex is stored by the enclosing regex. The inner regex is invoked by the outer regex during pattern matching. The inner regex participates fully in the match, back-tracking as needed to make the match succeed.
Consider these 2 ways of defining a regexp matching an uri (probably sub-optimal and not 100%, but the point is not on this topic).
If the expression is defined in one go, execution is around 6x faster than if the same regex is built from 3 sub regex.
Consider this code snippet
#include <iostream>
#include <string>
#include <chrono>
#include <boost/xpressive/xpressive.hpp>
using namespace boost::xpressive;
void bench_regex(const sregex& regex)
{
std::string positive = "asdas http://www.foo.io/bar asdp https://www.bar.io ";
std::string negative = "sdaoas dof jdfjo fds dsf http:/www.nonono .sa ";
const int nb_iterations = 100'000;
int nmatch = 0;
smatch what;
std::chrono::steady_clock::time_point begin0 = std::chrono::steady_clock::now();
for (int i = 0 ; i < nb_iterations; ++i)
{
if (regex_search( positive, what, regex ))
nmatch++;
if (regex_search( negative, what, regex ))
nmatch++;
}
std::chrono::steady_clock::time_point end0 = std::chrono::steady_clock::now();
std::cout << "nb matchs " << nmatch << std::endl;
std::cout << "search time " << std::chrono::duration_cast<std::chrono::microseconds>(end0-begin0).count()/1000.0f <<"ms" << std::endl << std::endl;
}
int main()
{
{
std::cout << "regex in one piece" << std::endl;
const sregex regex_uri_standalone = alpha >> *alnum >> "://" >> + ~(set= ' ','/') >> !( *('/' >> ~(set=' ')));
bench_regex(regex_uri_standalone);
}
{
std::cout << "regex built from part" << std::endl;
const sregex scheme = alpha >> *alnum;
const sregex hostname = + ~(set= ' ','/');
const sregex path = !( *('/' >> ~(set=' ')));
const sregex regex_uri_built_from_subregex = scheme >> "://" >> hostname >> path;
bench_regex(regex_uri_built_from_subregex);
}
}
This is particularly annoying because a main force of Xpressive is the ability to construct complex regexp from simplier one, which can be quickly become a nightmare if using pcre or equivalent.
But if it comes with such a performance cost, the benefit looks annihilated.
btw, is the library still maintained ? according to boost changelog, no change since boost 1.55 (11Nov 2013 !)
https://www.boost.org/users/history/

No you can't get around the function invocation / type erasure overhead of sregex instance, because the expression template has already been compiled.
What you can do instead, is use deduced type for the sub-expressions:
using boost::proto::deep_copy;
std::cout << "regex built from auto" << std::endl;
const auto scheme = deep_copy(xp::alpha >> *xp::alnum);
const auto hostname = deep_copy(+~(xp::set = ' ', '/'));
const auto path = deep_copy(!(*('/' >> ~(xp::set = ' '))));
Be aware that the deep_copy is absolutely necessary to avoid dangling references to temporaries since you're naming the expressions now. The good news is that on my system, the result is slightly faster than before:
Live On Coliru
Printing
regex in one piece nb matchs 100000 search time 180.01ms
regex built from auto nb matchs 100000 search time 170.172ms
But Let's Speed It Up
There's Boost Spirit, which has a very similar parser expression language. I think it's just simply more modern. Let's try and compare!
Live On Coliru
#include <chrono>
#include <iostream>
#include <string>
double do_xp_test();
double do_x3_test();
int main() {
auto xp = do_xp_test();
auto x3 = do_x3_test();
std::cout << "x3 took ~" << (x3/xp*100.0) << "% of the xpressive time\n";
}
auto now = std::chrono::steady_clock::now;
using namespace std::chrono_literals;
static std::string const positive = "asdas http://www.foo.io/bar asdp https://www.bar.io ";
static std::string const negative = "sdaoas dof jdfjo fds dsf http:/www.nonono .sa ";
constexpr int nb_iterations = 100'000;
#include <boost/xpressive/xpressive.hpp>
namespace xp = boost::xpressive;
double bench_regex(const xp::sregex& regex) {
unsigned nmatch = 0;
xp::smatch what;
auto begin0 = now();
for (int i = 0; i < nb_iterations; ++i) {
if (regex_search(positive, what, regex))
nmatch++;
if (regex_search(negative, what, regex))
nmatch++;
}
auto elapsed = (now() - begin0) / 1.0ms;
std::cout << "nb matchs " << nmatch << "\telapsed " << elapsed << "ms\n";
return elapsed;
}
double do_xp_test() {
using boost::proto::deep_copy;
std::cout << "regex built from auto\t";
const auto scheme = deep_copy(xp::alpha >> *xp::alnum);
const auto hostname = deep_copy(+~(xp::set = ' ', '/'));
const auto path = deep_copy(!(*('/' >> ~(xp::set = ' '))));
const xp::sregex regex_uri_built_from_subregex =
scheme >> "://" >> hostname >> path;
return bench_regex(regex_uri_built_from_subregex);
}
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
double bench_x3(auto parser_expression) {
auto const search_expr = x3::seek[x3::raw[parser_expression]];
[[maybe_unused]] std::string what;
auto begin0 = now();
unsigned nmatch = 0;
for (int i = 0; i < nb_iterations; ++i) {
if (parse(begin(positive), end(positive), search_expr/*, what*/))
nmatch++;
if (parse(begin(negative), end(negative), search_expr/*, what*/))
nmatch++;
}
auto elapsed = (now() - begin0) / 1.0ms;
std::cout << "nb matchs " << nmatch << "\telapsed " << elapsed << "ms\n";
return elapsed;
}
double do_x3_test() {
std::cout << "spirit x3 from subs\t";
const auto scheme = x3::alpha >> *x3::alnum;
const auto hostname = +~x3::char_(" /");
const auto path = *('/' >> +~x3::char_(' '));
const auto uri_built_from_subs = scheme >> "://" >> hostname >> path;
return bench_x3(uri_built_from_subs);
}
Prints
regex built from auto nb matchs 100000 elapsed 156.939ms
spirit x3 from subs nb matchs 100000 elapsed 93.3622ms
x3 took ~59.4897% of the xpressive time
Or on my system,
Related: Boost URL
For actual handling of URLs (not detection) I suggest using the newly accepted Boost URL library.

Related

problem in implementing google authenticator app in c++

i am trying to implement google Authenticator mechanism in c++.
i always get different OTP than that of google authenticator.
i wonder why ?
1 - i searched and found that google uses HMAC-SHA1 algorithm. but i am suspecious because :
almost all articles i have read are old. seems irrelevent.
i found that google authenticator code is now private before it was
open source. so am afraid google might changed the algorithim used
i found that SHA1 is no longer secure. some people managed to make
SHA1-collision. i would be surprized if google still uses it instead of
other more secure algorithms like SHA256,SHA512.
if you have any information regarding that, please inform me.
2 - i am sure my code is correct.
because i compared the output Hash value to automatically generated one
in this website, and they always match.
the website : https://www.liavaag.org/English/SHA-Generator/HMAC/
because code is pretty simple!
here's the code :
/*****************************************************************************************/
#include <iostream>
#include <cmath>
#include <ctime>
#include <stdio.h>
#include <string>
#include "SHA1.h"
#include "HMAC_SHA1.h"
using namespace std;
void IntegerToString(time_t epochTime, BYTE timeAsString[] , int length);
int TimeLength(time_t epochTime);
int main(void)
{
CHMAC_SHA1 sha1;
int one,two,three,four;
time_t result = time(nullptr);
result = (long long)floor(result/30);
cout << result <<endl;
int offset;
int truncatedHash;
int finalOTP;
BYTE key[33] = "atoqb4y572clkhj2sls5h72a76cnyzpe";
int key_len = 33; /*32 + null terminator*/
int text_len = TimeLength(result);
//cout << text_len << endl;
BYTE text[text_len+1];
IntegerToString(result , text , text_len);
text[text_len] = '\0';
//printf("%s",text);
/*the digest is always 20 bytes long*/
BYTE digest[20] = {0};
sha1.HMAC_SHA1(text,text_len,key,key_len-1,digest);
printf("0x");
for(int i = 0 ; i < 20 ; i++)
{
printf("%x",(int)digest[i]);
}
offset = digest[19] & 0xf;
one = (digest[offset+0] & 0x7f) << 24;
two = (digest[offset+1] & 0xff) << 16;
three = (digest[offset+2] & 0xff) << 8;
four = (digest[offset+3] & 0xff);
truncatedHash = one | two | three | four;
finalOTP = (truncatedHash % (1000000));
cout << "\nyour OTP : " << finalOTP << endl;
return 0;
}
void IntegerToString(time_t epochTime, BYTE timeAsString[] , int length)
{
time_t reverse = 1; /*to hold zeros*/
int i = 0;
while(epochTime >= 1) /*reverse : 1000 -> 10001*/
{
reverse = reverse*10+epochTime%10;
epochTime = epochTime / 10;
//cout << epochTime << "*" << reverse <<endl;
}
while(reverse != 1)
{
timeAsString[i] = (reverse%10 +'0');
reverse = reverse / 10;
//cout << i << timeAsString[i] << "#" << reverse << endl;
i++;
}
}
int TimeLength(time_t epochTime)
{
int counter = 0;
while(epochTime)
{
epochTime = epochTime / 10;
counter++;
}
return counter;
}
please help.
The key you use atoqb4y572clkhj2sls5h72a76cnyzpe does not seem to be in hex format.
You should be using hex (hex of your string is 04dd00f31dfe84b51d3a92e5d3ff40ff84dc65e4 If you need to use base32, you need to convert it to hex first
This repo works out perfectly: https://github.com/RavuAlHemio/cpptotp
Just tested.
steps on ubuntu:
git clone https://github.com/RavuAlHemio/cpptotp.git
cd cpptotp/
mkdir build
cd build/
cmake ..
make
./gauche
Input your key

How to use spirit X3 parse into a class with constructor containing parameters?

I am a new man on using spirit x3, I read some document from official site or from other github repositories. But, I can not find how to parse into a class with parameters. I referred to the former question: Boost-Spirit (X3) parsing without default constructors
I wrote a sample to test it, I will present my codes in the following area. My pain is how to use x3::_attr, and how to pass parsed parameters to the class constructor?
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <vector>
struct MyPair {
MyPair(int x, int y) : mx(x), my(y) {};
int mx;
int my;
};
class MyDu {
public:
MyDu() {};
MyDu(int x, int y) : mx(x), my(y) {};
int mx;
int my;
};
int main()
{
namespace x3 = boost::spirit::x3;
using x3::int_;
std::vector<MyPair> pairs;
MyDu myDu;
char const *first = "11:22", *last = first + std::strlen(first);
//auto pair = x3::rule<struct pair_, std::vector<MyPair> >{}
// = (int_ >> ':' >> int_)
// [([&](auto& ctx) {
// auto& attr = x3::_attr(ctx);
// using boost::fusion::at_c;
// return x3::_val(ctx).emplace_back(at_c<0>(attr), at_c<1>(attr));
// })]
//;
auto pair = x3::rule<class MyDu_, MyDu >{}
= (int_ >> ':' >> int_)
[([&](auto& ctx) {
auto& attr = x3::_attr(ctx);
using boost::fusion::at_c;
//return x3::_val(ctx)(at_c<0>(attr), at_c<1>(attr));
ctx = MyDu(at_c<0>(attr), at_c<1>(attr));
return x3::_val(ctx);
})]
;
//bool parsed_some = parse(first, last, pair % ',', pairs);
bool parsed_some = parse(first, last, pair, myDu);
if (parsed_some) {
std::cout << "Parsed the following pairs" << std::endl;
//for (auto& p : pairs) {
// std::cout << p.mx << ":" << p.my << std::endl;
//}
std::cout<<myDu.mx<<","<<myDu.my<<std::endl;
}
system("pause");
}
Any one who can fix my error, and parse into a class in my code ? Thanks!
Perhaps you were missing the way to assign to the rule's value using _val:
Live On Coliru
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <vector>
struct MyDu {
MyDu(int x, int y) : mx(x), my(y){};
int mx;
int my;
};
int main() {
namespace x3 = boost::spirit::x3;
using x3::int_;
MyDu myDu{1,2};
std::string const s = "11:22";
auto assign = [](auto& ctx) {
using boost::fusion::at_c;
auto& attr = x3::_attr(ctx);
x3::_val(ctx) = MyDu(at_c<0>(attr), at_c<1>(attr));
};
auto pair = x3::rule<class MyDu_, MyDu>{} = (int_ >> ':' >> int_)[assign];
if (parse(begin(s), end(s), pair, myDu)) {
std::cout << "Parsed: " << myDu.mx << ", " << myDu.my << "\n";
}
}
Prints
Parsed: 11, 22
Oh, fantastic! Many thanks, sehe, you help me solve the problem bothering me for some while.
In fact I can not find document on spirit how to use attr, i only find a doc from "Ruben-Van-Boxem-Parsing-CSS-in-C-with-Boost-Spirit-X3",
_val :A reference to the attribute of the innermost rule invoking _where :the parser Iterator range to the input stream
_attr : A reference to the a˛ribute of the parser
_pass: A reference to a bool flag that can be used to force the parser to fail
could you share some info on these parameters. Many thanks again!

c++, problems with cin? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I wrote a small test to figure out the fastest mathematic operation for a special x. I wanted the x to be entered by the user, so that I can run the tests for different x. In the following code I tells me that there is an error with std::cin >> val;
error: cannot bind 'std::istream {aka std::basic_istream}' lvalue to 'std::basic_istream&&'
If I declare val as double valinstead of const double val I get more errors. What can I change in order to have a running programm?
#include <cmath>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <istream>
#include <ostream>
// for x^1.5
double test_pow_15(double x) { return std::pow(x, 1.5); };
double test_chain_15(double x) { return sqrt(x * x * x); };
double test_tmp_15(double x) { double tmp = x * x * x; return sqrt(tmp); };
volatile double sink;
const double val = 0;
const double ans_15 = std::pow(val, 1.5);
void do_test(const char* name, double(&fn)(double), const double ans) {
auto start = std::chrono::high_resolution_clock::now();
for (size_t n = 0; n < 1000 * 1000 * 10; ++n) {
sink = val;
sink = fn(sink);
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> dur = end - start;
std::cout << name << ".Took" << dur.count() << "ms, error:" << sink - ans << '\n';
}
int main()
{
std::cout << "Speed test"<< '\n';
std::cout << "Please enter value for x."<< '\n';
std::cout << "x = ";
std::cin >> val;
std::cout << "Speed test starts for x = "<< val <<"."<<'\n';
std::cout << " " << '\n';
std::cout << "For " << val<<"^(1.5) the speed is:" <<'\n';
do_test("std::pow(x,1.5) ",test_pow_15, ans_15);
do_test("sqrt(x*x*x) ",test_chain_15, ans_15);
do_test("tmp = x*x*x; sqrt(tmp) ",test_tmp_15, ans_15);
return 0;
}
I think if you remove the "const" keyword, it would probably work fine.
double val = 0;

How to use boost::xpressive for populating a vector with structs within a semantic action

I was trying to insert a data struct into a vector everytime a match is detected, but i am failing even in compiling. The code is next:
#include <string>
#include <boost/xpressive/xpressive.hpp>
#include <boost/xpressive/regex_actions.hpp>
using namespace boost::xpressive;
struct Data
{
int integer;
double real;
std::string str;
Data(const int _integer, const double _real, const std::string& _str) : integer(_integer), real(_real), str(_str) { }
};
int main()
{
std::vector<Data> container;
std::string input = "Int: 0 - Real: 18.8 - Str: ABC-1005\nInt: 0 - Real: 21.3 - Str: BCD-1006\n";
sregex parser = ("Int: " >> (s1 = _d) >> " - Real: " >> (s2 = (repeat<1,2>(_d) >> '.' >> _d)) >> " - Str: " >> (s3 = +set[alnum | '-']) >> _n)
[::ref(container)->*push_back(Data(as<int>(s1), as<double>(s2), s3))];
sregex_iterator cur(input.begin(), input.end(), parser);
sregex_iterator end;
for(; cur != end; ++cur)
smatch const &what = *cur;
return 0;
}
It is failing in compile the "push_back" semantic action due to I am using a Data object inside and it is not able to use it lazinessly (I guess, I am not really sure).
Please, could anyone help me with this?
Note- I am unluckily tied to MS VS 2010 (not fully c++11 compliant), so please don't use variadic templates and emplace_back solutions. Thank you.
Using Xpressive
You should make the action a lazy actor. Your Data constructor call isn't.
Live On Coliru
#include <string>
#include <boost/xpressive/xpressive.hpp>
#include <boost/xpressive/regex_actions.hpp>
namespace bex = boost::xpressive;
struct Data {
int integer;
double real;
std::string str;
Data(int integer, double real, std::string str) : integer(integer), real(real), str(str) { }
};
#include <iostream>
int main() {
std::vector<Data> container;
std::string const& input = "Int: 0 - Real: 18.8 - Str: ABC-1005\nInt: 0 - Real: 21.3 - Str: BCD-1006\n";
using namespace bex;
bex::sregex const parser = ("Int: " >> (s1 = _d) >> " - Real: " >> (s2 = (repeat<1,2>(_d) >> '.' >> _d)) >> " - Str: " >> (s3 = +set[alnum | '-']) >> _n)
[bex::ref(container)->*bex::push_back(bex::construct<Data>(as<int>(s1), as<double>(s2), s3))];
bex::sregex_iterator cur(input.begin(), input.end(), parser), end;
for (auto const& what : boost::make_iterator_range(cur, end)) {
std::cout << what.str() << "\n";
}
for(auto& r : container) {
std::cout << "[ " << r.integer << "; " << r.real << "; " << r.str << " ]\n";
}
}
Prints
Int: 0 - Real: 18.8 - Str: ABC-1005
Int: 0 - Real: 21.3 - Str: BCD-1006
[ 0; 18.8; ABC-1005 ]
[ 0; 21.3; BCD-1006 ]
Using Spirit
I'd use spirit for this. Spirit has the primitives to directly parse to underlying data types, which is less error prone and more efficient.
Spirit Qi (V2)
Using Phoenix, it's pretty similar: Live On Coliru
Using Fusion adaptation, it gets more interesting, and a lot simpler:
Live On Coliru
Now imagine:
You wanted to match the keywords case insensitive
You wanted to make whitespace insignificant
You wanted to accept empty lines, but not random data in between
How would you do that in Xpressive? Here's how you'd do it with Spirit. Note how the additional constraints do not change the grammar, essentially. Contrast that with regex-based parsers.
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct.hpp>
namespace qi = boost::spirit::qi;
struct Data {
int integer;
double real;
std::string str;
};
BOOST_FUSION_ADAPT_STRUCT(Data, integer, real, str);
#include <iostream>
int main() {
std::vector<Data> container;
using It = std::string::const_iterator;
std::string const& input = "iNT: 0 - Real: 18.8 - Str: ABC-1005\n\nInt: 1-Real:21.3 -sTR:BCD-1006\n\n";
qi::rule<It, Data(), qi::blank_type> parser = qi::no_case[
qi::lit("int") >> ':' >> qi::auto_ >> '-'
>> "real" >> ':' >> qi::auto_ >> '-'
>> "str" >> ':' >> +(qi::alnum|qi::char_('-')) >> +qi::eol
];
It f = input.begin(), l = input.end();
if (parse(f, l, qi::skip(qi::blank)[*parser], container)) {
std::cout << "Parsed:\n";
for(auto& r : container) {
std::cout << "[ " << r.integer << "; " << r.real << "; " << r.str << " ]\n";
}
} else {
std::cout << "Parse failed\n";
}
if (f != l) {
std::cout << "Remaining input: '" << std::string(f,l) << "'\n";
}
}
Still prints
Parsed:
[ 0; 18.8; ABC-1005 ]
[ 1; 21.3; BCD-1006 ]
Further thoughts: how would you
Parse scientific notation? Negative numbers?
Parse decimal numbers correctly (assuming you are really parsing financial amounts, you may not wish inexact floating point representations)
Spirit X3
If you can use c++14, Spirit X3 can be more efficient, and compile a lot faster than either the Spirit Qi or the Xpressive approach:
Live On Coliru
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/struct.hpp>
struct Data {
int integer;
double real;
std::string str;
};
BOOST_FUSION_ADAPT_STRUCT(Data, integer, real, str);
namespace Parsers {
using namespace boost::spirit::x3;
static auto const data
= rule<struct Data_, ::Data> {}
= no_case[
lit("int") >> ':' >> int_ >> '-'
>> "real" >> ':' >> double_ >> '-'
>> "str" >> ':' >> +(alnum|char_('-')) >> +eol
];
static auto const datas = skip(blank)[*data];
}
#include <iostream>
int main() {
std::vector<Data> container;
std::string const& input = "iNT: 0 - Real: 18.8 - Str: ABC-1005\n\nInt: 1-Real:21.3 -sTR:BCD-1006\n\n";
auto f = input.begin(), l = input.end();
if (parse(f, l, Parsers::datas, container)) {
std::cout << "Parsed:\n";
for(auto& r : container) {
std::cout << "[ " << r.integer << "; " << r.real << "; " << r.str << " ]\n";
}
} else {
std::cout << "Parse failed\n";
}
if (f != l) {
std::cout << "Remaining input: '" << std::string(f,l) << "'\n";
}
}
Prints (it's getting boring):
Parsed:
[ 0; 18.8; ABC-1005 ]
[ 1; 21.3; BCD-1006 ]

C++11 app that uses dispatch_apply not working under Mac OS Sierra

I had a completely functioning codebase written in C++11 that used Grand Central Dispatch parallel processing, specifically dispatch_apply to do the basic parallel for loop for some trivial game calculations.
Since upgrading to Sierra, this code still runs, but each block is run in serial -- the cout statement shows that they are being executed in serial order, and CPU usage graph shows no parallel working on.
Queue is defined as:
workQueue = dispatch_queue_create("workQueue", DISPATCH_QUEUE_CONCURRENT);
And the relevant program code is:
case Concurrency::Parallel: {
dispatch_apply(stateMap.size(), workQueue, ^(size_t stateIndex) {
string thisCode = stateCodes[stateIndex];
long thisCount = stateCounts[stateIndex];
GameResult sliceResult = playStateOfCode(thisCode, thisCount);
results[stateIndex] = sliceResult;
if ((stateIndex + 1) % updatePeriod == 0) {
cout << stateIndex << endl;
}
});
break;
}
I strongly suspect that this either a bug, but if this is GCD forcing me to use new C++ methods for this, I'm all ears.
I'm not sure if it is a bug in Sierra or not. But it seems to work if you explicitly associate a global concurrent queue as target:
dispatch_queue_t target =
dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
dispatch_queue_t workQueue =
dispatch_queue_create_with_target("workQueue", DISPATCH_QUEUE_CONCURRENT, target);
// ^~~~~~~~~~~ ^~~~~~
Here is a working example
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <sstream>
#include <dispatch/dispatch.h>
void load_problem(const std::string, std::vector<std::pair<double,double>>&);
int main() {
// n-factor polynomial - test against a given problem provided as a set of space delimited x y values in 2d.txt
std::vector<std::pair<double,double>> problem;
std::vector<double> test = {14.1333177226503,-0.0368874860476915,
0.0909424058436257,2.19080982673558,1.24632025036125,0.0444549880462031,
1.06824631867947,0.551482840616757, 1.04948148731933};
load_problem("weird.txt",problem); //a list of space delimited doubles representing x, y.
size_t a_count = test.size();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block double diffs = 0.0; //sum of all values..
dispatch_apply(problem.size(), queue, ^(size_t i) {
double g = 0;
for (size_t j=0; j < a_count - 1; j++) {
g += test[j]*pow(problem[i].first,a_count - j - 1);
}
g += test[a_count - 1];
diffs += pow(g - problem[i].second,2);
});
double delta = 1/(1+sqrt(diffs));
std::cout << "test: fit delta: " << delta << std::endl;
}
void load_problem(const std::string file, std::vector<std::pair<double,double>>& repo) {
repo.clear();
std::ifstream ifs(file);
if (ifs.is_open()) {
std::string line;
while(getline(ifs, line)) {
double x= std::nan("");
double y= std::nan("");
std::istringstream istr(line);
istr >> std::skipws >> x >> y;
if (!isnan(x) && !isnan(y)) {
repo.push_back({x, y});
};
}
ifs.close();
}
}

Resources