Hello,

I am trying to implement a for loop which fills (and re-sizes) a temp matrix (temp_data) based on a column value criteria from another matrix (data). The data matrix comes from a text file which has the format:
a b c d e f g h 1
i s o e k n s i 1
w j r v d f a q 1
i n s e v y h a 1
o x d g q e s p 2
p q a i d f x w 2
o d s c n q e d 2

basically, there is a bunch of stock price data, always 8 columns long, with an identifier in the 9th column.

I want to create a temporary matrix in the first loop which contains only the rows with "1" in column 9, then in the next loop with "2" and so on... During each loop I will run a series of functions and output results, appending a results matrix after each loop.

This is a snippet of the code that I added to my source file:

double temp_data = NULL;  //temporary matrix
int u = 654;			// u = the total number of periods in the time series
	for (int i=1; i<=u; i++)
	{
		if(data[n][k] == 'i')
		{
			temp_data = data[n][k];
		}

       ******a bunch of other code here*******     

	}

Please don't laugh at me - I really don't know C++ and I am finding this difficult. Basically, the temp_data is not filling with values. It may be that the data[n][k] array is the problem. I could take directly from the .txt data file but I thought I would try to pull from an already populated matrix earlier in the code.

I am aware that I haven't even addressed how to realloc memory for a matrix but I guess that will have to come later :-0

I can post more of my code if necessary.

Thank you so much for any insights.

bk

Recommended Answers

All 3 Replies

Hello,

double temp_data = NULL;  //temporary matrix
int u = 654;			// u = the total number of periods in the time series

bk

There are some inconsistancies in your descriptions and implementation.

If this isn't an assignment there are quicker ways to load the data.

1st this line is definitely wrong

double temp_data = NULL;

temp_data is a variable that you are assigning a value
and it like an int can only store one value

what is data nk??

I would try to use vectors:

#include <vector>
#include <iostream>

int main
{
  std::vector<double> row;
  std::vector<std::vector<double>> mat;
 double val (0.0);
  int current(0);
  for(int i = 0; i < 8;  ++i)
  {
   std::cout << "enter val:";
   std::cin >> val;
   row.push_back(val);
  }

  int id;
  std::cout << "enter id:";
  std::cin >>id;
  if(id == current)
  { 
      mat.push_back(row);
   }
   else
   {
      std::cout << "different block" << std::endl;
      current = id;
   } 
   return 0;
  }

this code clearly only does part of the job and is doing a cin
rather than loading from the file

a vector is extensible and could be used to build a class for loading in your data it saves you having to use new and delete []

Thanks for your response. I should clarify that the data is all doubles (no char). And the data is read in previously to this segment like this:

// Read in data
	int count = 0;
	#if defined(WIN32)
		while(fscanf_s(f_data, "%lf", &input_data) != EOF) //The last line is cast away systematically
	#elif defined(__linux__)
		while(fscanf(f_data, "%lf\n", &input_data) != EOF)
	#endif
       	{
			count++;
			data_options = (double*) realloc (data_options, count * sizeof(double)); 
			if (data_options==NULL)
			{
				  puts ("Error (re)allocating memory");
				  exit (1);
			}
			
			data_options[count-1]=input_data; 
	  } //close while-loop

		numobs = count/Dim2;   // count is the number of datapoints, Dim2 is the number of columns for each observation

		data = zweidmatrix(numobs,Dim2);
		for (n=0; n<numobs; n++) 
		{
			for (k=0; k<Dim2; k++)
			{
				data[n][k]=data_options[n*Dim2+k];
			}
		}

	fclose(f_data); 
	free(data_options);

Any help on the logic for creating a subset of the data in a temp matrix from the data that's already been read in, would be greatly appreciated.

You are using a lot of c code rather than c++ and stl
this makes your code tricky to read.

first an aside it is probably worth moving if(WIN32) to be just a single string definition rather than in the middle of a while loop as it gets tricky to read.

so first you have your big
2-D array

a b c d e f g h 1
....

z x c v b n h j 4

now you can either load in just the values or the values plus the keys

#include  <vector>// dynamic handles the resizing for you

//make the code more readable
typedef std::vector<double> vd;
typedef std::vector<vd> vvd;

class matrix_loader
{
public:
   matrix_loader(int width = 8);   
   bool load_from_file(char * fn);
   std::vector<vvd> get_all_blocks();
   void clear(); //0 every thing
   void set_width(int nw){width = nw;}

private:
   int my_width;
  vvd data; // just values
   std::vector<int> ids; //last column
};

this gives a class where vvd is the desired structure that you want to use

now need to write implementation

#include "matrix_loader.h"
#include <fstream>

matrix_loader::matrix_loader()
:my_width(width)
{
}

void matrix_loader::clear()
{
my_width = 0;
ids.clear();
data.clear();
}

bool  matrix_loader::load(c har *fn)
{
 clear();
//reading in data using stl
 std::ifstream fin(fn, std::ios::in);
 if(fin.is_open() == true)
 {
    //iterate get_line while ..
    int max_count(100000); //overflow protection
    int count(0);
    while(count < max_count)
   {
     vd row;
     for(int j(0) j < my_width; ++j) 
     { 
       double d;
       fin >> d; //read in the double
       row.push_back(d);
     }
     int id;
     fin >> id;
     if(id <= 0)
     {
        //no line
        break;
      }
      else
      {
        //store id 
       ids.push_back(id);
       }
   }
    data.push_back(row);
    ++count;
  }
    
     fin.close();
 }
}

The load looks messy but it just reads in the data assuming
double double double .. int on each row

now get a vector of new blocks

std::vector<vvd> matrix_loader::get_all_blocks()
{
 std::vector<vvd> temp;
  vvd temp;
  int sz = ids.size();
  //check all ids to see for change
  if(sz > 0)
  {
   int id = ids[0];
   temp.push_back(data[0]);
   for(int j = 1; j < sz; ++j)
   {
       vd current_row = data[j]
       int current_id = ids[j];
       if(id != current_id)
      {
         //new block
         ret.push_back(temp);
         temp.clear();
         id = current_id;
       }
       temp.push_back(curent_row);
    }
//have a block still to write
         ret.push_back(temp);
  }
}

now the return of get all blocks is all of the new vvd that you wanted

now althoug hresizing can be done without vector it is easiest this way
the vvd could be changed to a class

this design should wrk but you may find confusing due to using c++ methods. It is well worth using vector though and it has some unusual function names but it is very useful.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.