Getting Data: undeclared identifier and 'std::vector': 'Data' is not a valid template type argument for parameter '_Ty'

I'm using a linear regression algorithm and I keep getting Data: undeclared identifier and 'std::vector': 'Data' is not a valid template type argument for parameter '_Ty'. I tried putting the Data definition in the header file but then it tells me Data is undefined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "LinearRegression.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <string>

struct Data { double x, y; };

std::vector<Data> LinearRegression::transform(const std::vector<OrderBookEntry>& ordersX, const std::vector<OrderBookEntry>& ordersY) {
    std::vector<Data> result(ordersX.size());
    for (int i = 0; i < ordersX.size(); ++i) {
        result[i] = { ordersX[i].price, ordersY[i].price };
    }
    return result;
}

void LinearRegression::regression(const std::vector<Data>& data, double& m, double& c)
{
    int N = data.size();
    double Sx = 0, Sy = 0, Sxx = 0, Sxy = 0, Syy = 0;
    for (Data d : data)
    {
        double x = d.x, y = d.y;
        Sx += x;
        Sy += y;
        Sxx += x * x;
        Sxy += x * y;
        Syy += y * y;
    }
    m = (N * Sxy - Sx * Sy) / (N * Sxx - Sx * Sx);
    c = (Sy - m * Sx) / N;
}

void LinearRegression::training(const std::vector<Data>& data, double& m, double& c, double alpha, int passes)
{
    m = c = 0.0;
    while (passes--)
    {
        for (Data d : data)
        {
            double error = m * d.x + c - d.y;
            c -= alpha * error;
            m -= alpha * error * d.x;
        }
    }
}

void LinearRegression::write(const std::vector<Data>& data, double m, double c)
{
#define fmt << std::setw( 20 ) <<
    std::cout << "Regression line is y = " << m << "x + " << c << "\n\n";
    std::cout << std::fixed << std::setprecision(6);
    std::cout << "For comparison (x, y, ypred):\n";
    for (Data d : data) std::cout fmt d.x fmt d.y fmt m* d.x + c << '\n';
}

void LinearRegression::gradientDescent(std::vector<OrderBookEntry>& ordersX, std::vector<OrderBookEntry>& ordersY)
{
    double m, c;                        
    std::vector<Data> data = transform(ordersX, ordersY);
    regression(data, m, c);
    write(data, m, c);
}


LinearRegression.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once

#include "OrderBook.h"
#include <iomanip>
#include <vector>

class LinearRegression
{
	public:
		std::vector<Data> transform(const std::vector<OrderBookEntry>& ordersX, const std::vector<OrderBookEntry>& ordersY);
		void regression(const std::vector<Data>& data, double& m, double& c);
		void training(const std::vector<Data>& data, double& m, double& c, double alpha, int passes);
		void write(const std::vector<Data>& data, double m, double c);
		void gradientDescent(std::vector<OrderBookEntry>& ordersX, std::vector<OrderBookEntry>& ordersY);
};
Last edited on
You might at least credit the code which you've managed to destroy!
http://www.cplusplus.com/forum/general/274766/#msg1185918

Need to see what's in the rest of your code.

Oh sorry. I wasn't aware we had to put sources for the code we post. I'll do it next time. Do you need the header file? This is pretty much all the code because I don't think the code in my other classes affect this. Only thing I changed was the vector.
Last edited on
Well, let's see the header LinearRegression.h.

It is patently untrue to say that the only thing you changed was the vector. You've moved a whole lot of standalone routines into a class (that we can't see) and you've called one procedure gradientDescent when it isn't, but left in (the unnecessary) routine training(), which did code up gradient descent. But I can't honestly see why you wanted to use gradient descent in the first place; it's not a particularly effective way to do linear regression.
Last edited on
The gradientDescent function was just a name I used previously for a gradient descent algorithm that I replaced with your code. I just haven't changed the name yet. I can give you some functions where the vectors I used were created?

These are from a file called OrderBook.cpp where the vector for the dataset is created.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/** return vector of all know products in the dataset*/
std::vector<std::string> OrderBook::getKnownProducts()
{
    std::vector<std::string> products;

    std::map<std::string,bool> prodMap;

    for (OrderBookEntry& e : orders)
    {
        prodMap[e.product] = true;
    }
    
    // now flatten the map to a vector of strings
    for (auto const& e : prodMap)
    {
        products.push_back(e.first);
    }

    return products;
}

/** return vector of Orders according to the sent filters*/
std::vector<OrderBookEntry> OrderBook::getOrders(OrderBookType type, 
                                                 std::string product, 
                                                 std::string timestamp)
{
    std::vector<OrderBookEntry> orders_sub;
    for (OrderBookEntry& e : orders)
    {
        if (e.orderType == type && 
            e.product == product && 
            e.timestamp == timestamp )
            {
                orders_sub.push_back(e);
            }
    }
    return orders_sub;
}

std::string OrderBook::getEarliestTime()
{
    return orders[0].timestamp;
}

std::string OrderBook::getNextTime(std::string timestamp)
{
    std::string next_timestamp = "";
    for (OrderBookEntry& e : orders)
    {
        if (e.timestamp > timestamp) 
        {
            next_timestamp = e.timestamp;
            break;
        }
    }
    if (next_timestamp == "")
    {
        next_timestamp = orders[0].timestamp;
    }
    return next_timestamp;
}


This is from my main file where I parse two vectors, one for product ask prices in current time and the other for next time, into your linear regression algorithm.

1
2
3
4
5
6
7
8
9
10
11
currentTime = orderBook.getEarliestTime();
nextTime = orderBook.getNextTime(currentTime);

for (std::string const& p : orderBook.getKnownProducts())
    {
        std::vector<OrderBookEntry> ordersX = orderBook.getOrders(OrderBookType::ask,
                                                                  p, nextTime);
        std::vector<OrderBookEntry> ordersY = orderBook.getOrders(OrderBookType::ask,
                                                                  p, currentTime);
        LR.gradientDescent(ordersX, ordersY);
    }


The sample dataset: https://wtools.io/paste-code/b2S8

I am not sure if these are useful for you to understand more about the problem so just tell me if you need more of my code. Do you need the CSVReader class I used to read in the sample dataset? Thanks for your help.
Last edited on
@ahmadalibin - the header file LinearRegression.h PLEASE!

Then it would at least be possible to compile your last code snippet as a stand-alone file (provided you don't have any more includes in the header).
@lastchance I already put the header in the original post. I thought you had seen it.
Your LinearRegression.h makes reference to the type Data; however, at this point Data has not been defined. You could simply move the declaration of the Data type to the top of LinearRegression.h instead of the cpp file.
@lastchance Thank you so much for all your time. You've been a big help and your linear regression algorithm is great.
Topic archived. No new replies allowed.