0

I have a numerical algorithm. I create a set of x, and y coordinates for points in R^2. Then, I use a rule to see which points are suitable for my purpose, a simple if statement like below:

int N = 0;
for (int i1 = -xN; i1 < xN + 1; i1++)
{
    for (int i2 = -yN; i2 < yN + 1; i2++)
    {
        double x = dist(0) * i1;
        double y = dist(1) *i2;
        
        if (sqrt(pow(x, 2) + pow(y, 2)) > 0.8 && abs(x) < 3.1 && abs(y) < 3.91)
        {
            Points.row(N) = trans(vec{ x, y});
            N = N + 1;
        }
    
    }
}

Since I change the rule (that is, sqrt(pow(x, 2) + pow(y, 2)) > 0.8 && abs(x) < 3.1 && abs(y) < 3.91) in each example, I was wondering if I could store it as a string variable and then save it with other parameters of the example in a single text file. something like this:

ofstream myfile;
myfile.open("resultEXAMPLE2D01.txt");
myfile << "xN = [" << xN << "];" << endl;
myfile << "N = [" << output.N << "];" << endl;
myfile << "% Condition is " << cond << endl;
myfile.close();

where "cond" should be "sqrt(pow(x, 2) + pow(y, 2)) > 0.8 && abs(x) < 3.1 && abs(y) < 3.91" in this case. So, in "cond" x and y are not variables, I just look at the whole thing as a text/string. but then inside the if statement I want to evaluate some criteria for x and y, so this "cond" should be a function with two doubles as input and a bool as output. Is there some straight forward way to have this kind of type conversion?

Iman
  • 3
  • 1
  • 1
    C++ is a compiled language, which means the string "sqrt(pow(x,2)+[...]" is not actually present anywhere in the compiled executable file (run the "strings" utility on the executable file if you want to verify that); rather it's been compiled down to machine code calling the addresses of the relevant math functions. So if you want to have your program write that string to a file, you'll need to include that string separately/explicitly in your program. – Jeremy Friesner Jul 30 '20 at 04:29
  • Would it be an option to turn the logistics around? I.e. instead of trying to store the copmiled condition into a string (which is impossible, as Jeremy explained above), why not store the string in the program which represents the condition and then add a parser which analyses the string during execution? That would of course be much slower and quite hard to implement, but it would at least be possible. – Yunnosch Jul 30 '20 at 05:16
  • JeremyFriesner Thanks for the clarification. @Yunnosch It would help me too. So I first define the condition as a string and then try to change it to a bool variable that could be evaluated for every x, and y. Can you explain how? – Iman Jul 30 '20 at 05:36
  • A boolean variable cannot be evaluated for different x,y. You need a parser to "understand" the string as a logical expression. Parsers are complex things to implement. too complex to explain here. You will probably have to read a little and look for tutorials. Maybe StackOverflow has some questions on the basic principle or on specific problems when implementing. The variable at the core is the string. – Yunnosch Jul 30 '20 at 05:41
  • I just thought of an alternative. You could decide to store the logical expression in an intermediate format, one which is easy to process for logic and easy to turn into a string representation for output. With your knowledge of possible use-cases that is probably the best way. How many and which operators need to be supported, sqrt, pow, `<`, `>`, `&&`, `abs`, .... what else? If you can enumerate them you are much closer to a simple solution. The need for a complete parser disappears then. – Yunnosch Jul 30 '20 at 05:43
  • @Yunnosch, the operators I need are these simple math operators. As far as I could search within my examples till know, this (sqrt, abs, pow, < , >, &&, or ) would be enough. – Iman Jul 30 '20 at 19:30

1 Answers1

1

Looks like you need Stringification. You can read more about it here:

So, you can define macros and pass to it your condition. Inside macros you can put your computation code, use passed condition and also stringify your condition (place #cond for cond paramater) for output to somewhere (file, console, ...).

Here is example:

int N = 0;

#define Calculate(cond) \
{ \
    N = 0; \
    for (int i1 = -xN; i1 < xN + 1; i1++) \
    { \
        for (int i2 = -yN; i2 < yN + 1; i2++) \
        { \
            double x = dist(0) * i1; \
            double y = dist(1) *i2; \
            \
            if (cond) \
            { \
                Points.row(N) = trans(vec{x, y}); \
                N = N + 1; \
            } \
     \
        } \
    } \
    \
    std::cout << "Condition: " << #cond << std::endl; \
}


int main()
{
    Calculate(sqrt(pow(x, 2) + pow(y, 2)) > 0.8 && abs(x) < 3.1 && abs(y) < 3.91)
    Calculate(x > 0)

    return 0;
}

Program output:

Condition: sqrt(pow(x, 2) + pow(y, 2)) > 0.8 && abs(x) < 3.1 && abs(y) < 3.91
Condition: x > 0
Ihor Drachuk
  • 1,265
  • 7
  • 17
  • I think I'd scale up the magic here and make two macros (which both use the same single macro defining the condition). One macro for evaluating the condition (but not the loops for the full calculation), one macro to output it. So I am not entirely happy, but the approach is valid and I missed it. I appreciate that. – Yunnosch Jul 31 '20 at 09:41
  • Hmm, maybe doing the calculation inside a/the macro is actually needed to achieve what OPs wants.... But you already got my upvote, can't have it again for being even more right than I thought at first... ;-) – Yunnosch Jul 31 '20 at 09:43
  • @Yunnosch, Actually, you can 'call' one macro from another one. Or put all needed code to only one. Or create macro `ComputeAndPrint` from where call two another macros forwarding same parameters – Ihor Drachuk Jul 31 '20 at 09:44