5 Replies - 1221 Views - Last Post: 13 April 2012 - 07:48 AM Rate Topic: -----

#1 LisaMarie0420  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 12-April 12

Error: Invalid conversion from double (*) to ...

Posted 12 April 2012 - 10:40 PM

I am trying to create an Optimization Program for a probability function. I have the functions in there that I used for my previous program but when I went to make a Golden Section, it is giving errors of:

In function ‘int main(int, char**)’:
error: invalid conversion from ‘double (*)(double, long int, long int)’ to ‘double (*)(double)’
error: initializing argument 4 of ‘double golden_section(double, double, double, double (*)(double))’


The exact like is 'cout << endl << "Answer" << golden_section(A, B, TOL, loglikelihood) << endl ;'.

#include <cstdlib>
#include <iostream>
#include <cmath>




using namespace std;




//double fofx(double x);
double loglikelihood(double p, long n, long k);
double golden_section(double a, double b, double tol, double (*f)(double));




/*
 * 
 */
int main(int argc, char** argv) {
    
    const double A = 0.0 ;
    const double B = 1.0 ;
    const double TOL = 0.001 ;
    cout << endl << "Answer" << golden_section(A, B, TOL, loglikelihood) << endl ;
    return 0;
}




double logfactorial(double n) {
    if (n > 1.0) {
        return log(n) + logfactorial(n - 1.0);
    } else {
        return 0;
    }
}




long logbinomial(double n, double k) {
    return logfactorial(n) - (logfactorial(k) + logfactorial(n - k));
}




//double fofx(double x){
//    return 0.5-x*exp(-x*x) ;
//}
double loglikelihood(double p, long n, long k) {
    return logbinomial(n, k) + k * log(p) + (n - k) * log(1.0 - p);
}




double golden_section(double a, double b, double tol, double (*f)(double)){
    const double TAU = (sqrt(5)-1)/2 ;
    double x1 = a+(1-TAU)*(b-a) ;
    double fx1 = f(x1) ;
    double x2 = a+(TAU)*(b-a) ;
    double fx2 = f(x2) ;
    int iter = 0 ;
    while((b-a)>tol){
        iter++ ;
        cout << "iter" << iter << " " << fx1 << " " << fx2 << endl ;
        if(fx1>fx2){
            
            a=x1 ;
            x1=x2 ;
            fx1=fx2 ;
            x2 = a+(TAU)*(b-a);
            fx2 = f(x2) ;
        }else{
            b=x2 ;
            x2=x1 ;
            fx2=fx1 ;
            x1= a+(1-TAU)*(b-a) ;
            fx1=f(x1) ;
        }
    }
    return a+(b-a)/2 ;
}


I have tried finding this error online with no luck. I have tried creating everything as a double or changing them all to longs. I will admit, I do not know much about this considering this is my first attempt at programming with these. Any help would be great. I based this program on one that I made in my class. The one I made in class (that worked) is where I commented things out (fofx).

I should also say that when I commented that line out (line28) to see if the program would run without it, the program builds and runs. Unfortunately, the entire program would not output anything at all.

Is This A Good Question/Topic? 0
  • +

Replies To: Error: Invalid conversion from double (*) to ...

#2 WaffleByte  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 12-April 12

Re: Error: Invalid conversion from double (*) to ...

Posted 12 April 2012 - 10:43 PM

I don't see a function or typedef named f() so you probably meant to put double *f as your 4th parameter instead.
Was This Post Helpful? 0
  • +
  • -

#3 LisaMarie0420  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 12-April 12

Re: Error: Invalid conversion from double (*) to ...

Posted 12 April 2012 - 11:40 PM

View PostWaffleByte, on 12 April 2012 - 10:43 PM, said:

I don't see a function or typedef named f() so you probably meant to put double *f as your 4th parameter instead.


I don't think I was doing the typedef correctly. I tried changing it, it wouldn't work. I understand that, when it comes to programming, I'm ignorant of many things. It's just frustrating because I went to my professor without any help. I even went to my school libraries and no one could help. My last resort is this because my classmates were just as lost.

This is my code when I tried to put it into the other program.
/* 
 * File:   main.cpp
 * Author: lmv11d (Lisa VanMiddlesworth)
 *
 * Created on March 14, 2012, 11:52 AM
 */

#include <cstdlib>
#include <iostream> //cout, cin
#include <fstream> // generate_gnuplot command
#include <sstream>
#include <vector> //vector commands
#include <numeric>
#include <string> //
#include <cmath> //log

using namespace std;

long factorial(long n)
{
    long i;
    long product = 1;
    for (i=2; i <= n; i++)
    {
        product = product * i;
    }
return product;
}

double logfactorial(double n) {
    if (n > 1.0) {
        return log(n) + logfactorial(n - 1.0);
    } else {
        return 0;
    }
}
// read the datafile into a vector of numbers

vector<long> readnumbers(void) {
    string filename;
    cout << "Please enter the data filename: ";
    cin >> filename;
    cout << "\nReading data from the file " << filename << "\n";
    string line;
    ifstream infile(filename.c_str()); //ifstream: use data from another program
    //c_str()): extracts the real string you need.

    if (!infile) { // Make sure it's a good file name.
        cerr << "File could not be found." << endl;
        exit(1);
    }
    vector <long> data; //a container for the bunch of numbers
    while (!infile.eof()) // To get you all the lines.
    {
        getline(infile, line); // Saves the line in STRING.
        long d = atol(line.c_str());
        data.push_back(d); 
       // cout << d << "\n";
    }
    //cout << "\n";
    infile.close();
    return data;
}

// counts the numbers of elements {1,2,3,4} (sides)
// and returns a vector with counts ordered for 1, 2, 3, 4, .. distinct elements

vector<long> empiricalCount(vector<long> v, long distinctElements) {
    vector<long> r;
    long i;
    long j;
    long c;
    for (i = 1; i <= distinctElements; i++) {
        //long c = count(v.begin(), v.end(), i); redone with a for loop below
        c=0;
        for (j=0; j<100; j++)
        {
            if (i==v[j])
            {
                c+=1;
            }
        }
        // cout << i << " " << c << "\n";
        r.push_back(c);
    }
    return r;
}

// log binomial function

long logbinomial(double n, double k) {
    return logfactorial(n) - (logfactorial(k) + logfactorial(n - k));
}

// log likelihood function

double loglikelihood(double p, long n, long k) {
    return logbinomial(n, k) + + k * log(p) + (n - k) * log(1.0 - p);
}

void generate_gnuplot() {
    ofstream outfile("plot.gnuplot");
    outfile << "plot [0.1:0.6] \"1\" using 2:3 lc rgb \"black\" lw .2 pt 0, \\\n";
    outfile << " \"2\" using 2:3 lc rgb \"red\" lw .2 pt 0,\\\n";
    outfile << " \"3\" using 2:3 lc rgb \"green\" lw .2 pt 0,\\\n";
    outfile << " \"4\" using 2:3 lc rgb \"blue\" lw .2 pt 0\\\n";
    outfile.close();
}

long calculate_sum(vector<long> counts){
    long i;
    long total = 0;
    for (i = 0; i < counts.size(); i++){
        total += counts[i];
    }
    return total;
}
double golden_section(double a, double b, double tol, double (*f)(double)) {
    const double TAU = (sqrt(5)-1)/2;
    double x1 = a + (1- TAU)*(b-a);
    double fx1 = f(x1);
    double x2 = a + (TAU)*(b-a);
    double fx2 = f(x2);
    int iter = 0;
    while ((b-a)>tol) {
        iter++;
        cout << "Iter. " << iter << " " << x1 << " " << fx1 << " " << x2 << " " << fx2 << endl;
        if (fx1>fx2) {
            a = x1;
            x1 = x2;
            fx1 = fx2;
            x2 = a + (TAU)*(b-a);
            fx2 = f(x2);
           
        } else {
            b = x2;
            x2 = x1;
            fx2 = fx1;
            x1 = a+ (1-TAU)*(b-a);
            fx1 = f(x1);
           
        }
    }
   
    return a + (b-a)/2;
}

//
//
// main routine
//
int main(int argc, char** argv) {
    double n;
    double k;
    double p;
    double incr = 0.001;
    long total = 0;
    long i;
    const double TOL = 0.001;
    const double A = 0.0;
    const double B = 1.0;
    //cout << endl << endl << "Answer: " << golden_section(A, B, TOL, loglikelihood) << endl;
    //ofstream outfile; found to be in wrong place
    //outfile.open("1"); kept so I would know where I went wrong

    vector <long> data = readnumbers();
    vector<long> counts = empiricalCount(data,4); //count the number of successes
    n = calculate_sum(counts);
    
    ofstream outfile;
    outfile.open("1");
    
    n = 100;
    k = counts[0];
    p = 0.0000001;
    while (p < 1.0)
    {
        double l = loglikelihood(p,n,k);
        cout << p << " " << l << endl;
        outfile << p << " " << l << endl;

        p = p + 0.01;
    }
    //outfile.close(); put in incorrect place
    //double 
    //loglikelihood(double p,long n,long k);
    //cout << l << endl; 
    
    outfile.close();
 
    generate_gnuplot();
        
    return 0;
}

double golden_section(double a, double b, double tol, double (*f)(double));

/*
 *
 */


//define the function itself
//double fofx(double x) {
//    return 0.5 - x*exp(-x*x);//want to optimize this function: a solver
    //want to create a solver as a function
//}




Was This Post Helpful? 0
  • +
  • -

#4 Hezekiah  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 208
  • View blog
  • Posts: 552
  • Joined: 12-July 09

Re: Error: Invalid conversion from double (*) to ...

Posted 13 April 2012 - 04:46 AM

double loglikelihood(double p, long n, long k);
double golden_section(double a, double b, double tol, double (*f)(double));

cout << endl << "Answer" << golden_section(A, B, TOL, loglikelihood) << endl ;

golden_section()'s last argument is a function taking one argument and loglikelihood() takes three, so you can't pass it as golden_section()'s last argument.
Was This Post Helpful? 0
  • +
  • -

#5 LisaMarie0420  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 12-April 12

Re: Error: Invalid conversion from double (*) to ...

Posted 13 April 2012 - 07:32 AM

Okay. So how do I fix it?
Was This Post Helpful? 0
  • +
  • -

#6 jimblumberg  Icon User is online

  • member icon


Reputation: 4292
  • View blog
  • Posts: 13,458
  • Joined: 25-December 09

Re: Error: Invalid conversion from double (*) to ...

Posted 13 April 2012 - 07:48 AM

Why are you passing a function pointer into the function? In the code provided I don't really see the need to pass the function pointer into your function. Do you have more than one function that you will want to use with golden_section()? If so all these functions must have the same return type and their parameters must be exactly the same type and number.

If you only have one function that you want to use with your golden_section() function then you do not need to pass a function pointer into the function. Just use the correct function where you are using the passed parameter.

Your function pointer signature must match the function signature you are trying to use.
The following must all match
// This function must match your function pointer below.
double loglikelihood(double p, long n, long k);
// In this prototype the last parameter must have the same number of 
// parameters as the actual function above.
double golden_section(double a, double b, double tol, double (*f)(double));



Jim
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1