I'm currently trying to multiply one of the matrices in my program with a constant but as there is no existing method to do that I guess I have to overload an operator or such. But as I have already overloaded it the " * " operator once. It also needs to take the value or more specifically the constant from the left side and not from the right. How do I proceed?
All help is appreciated!
The overloaded * operator
matrix operator * (matrix const arg){
double sum = 0;
int x = 0;
int rowY = 0;
int rowX = 0;
this->matrix_array_multiply = new double[row*arg.col];
for (int position = 0; position < row*arg.col; position++, x++){
if (arg.matrix_array[x*arg.row] == (arg.matrix_array[arg.row*arg.col])){
//If last number in second matrix, reset these values and proceed with next row of Y-values.
x = 0;
rowY++;
}
for (int y = 0; y < arg.row; y++, rowX++){
sum = sum + (matrix_array[y + (rowY*col)]) * (arg.matrix_array[x + (rowX*arg.col)]);
}
matrix_array_multiply[position] = sum;
rowX = 0;
sum = 0;
}
matrix new_matrix_multiply(matrix_array_multiply, row, arg.col); //Create new instance of new matrix.
return new_matrix_multiply; //Return new matrix.
}
Usage of the different matrices and operators:
int main () {
double a[] = { 3, 0, 3, 4,
3, 4, 2, 4,
5, 3, 2, 1 };
double b[] = { 6, 3, 5, 7,
9, 8, 6, 4,
6, 5, 3, 1 };
double c[] = { 1, 2, 3, 4,
5, 6, 7, 8,
9, 2, 1, 1,};
double d[] = { 6, 5, 4, 3,
2, 1, 0, 1,
2, 3, 4, 5,
6, 7, 8, 9};
double e[] = { 1, 2, 1,
3, 5, 7,
9, 7, 3};
matrix matrix1(a, 3, 4); //Instance of the class matrix: array, rows, columns.
matrix matrix2(b, 3, 4);
matrix matrix3(c, 3, 4);
matrix matrix4(d, 4, 4);
matrix matrix5(e, 3, 3);
matrix matrix6 = (matrix1 + matrix2);
matrix matrix7 = (matrix2 - matrix1);
matrix matrix8 = (matrix3 * matrix4);
matrix matrix9 = ~matrix5;
matrix matrix10 = (5.7 * matrix5); // Error: no operator "*" matches these operands, operand types are: double * matrix
}
Note: I've just started to learn c++ and this is part of a homework.
matrix matrix10 = (5.7 * matrix5);
For this to work, you've to define a free function with this signature:
matrix operator*(double c, matrix const & m) //non-member function
{
//your code
}
And likewise, you would like to define this also:
matrix operator*(matrix const & m, double c)
{
return c * m; //call the other overload!
}
Related
So the aim is to take two arrays as shown below
int x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int k[4] = {1, 2, 3, 4};
and add each element of k to each element of x in a loop as shown
1 2 3 4 5 6 7 8 9 10
+1 +2 +3 +4 +1 +2 +3 +4 +1 +2
This should give us a final array [2, 4, 6, 8, 6, 8, 10, 12, 10, 12].
Any suggestions as to how I could achieve this in C++
Loop through the indexes of the larger array, using the modulus (%) operator to wrap-around the indexes when accessing the smaller array.
int x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int k[4] = {1, 2, 3, 4};
int res[10];
for (int i = 0; i < 10; ++i) {
res[i] = x[i] + k[i % 4];
}
Online Demo
With % you can have the wrap-around behavior and with std::size(from C++17 onwards) the size of the array.
#include <algorithm>
#include <iostream>
int main()
{
int x[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int k[4] = {1, 2, 3, 4};
for(int i = 0; i < std::size(x); ++i)
{
x[i] = x[i] + k[i%std::size(k)];
}
//lets confirm if x has the right elmennts
for(const int& element: x)
{
std::cout<< element<<std::endl;
}
}
Note that here i have not used a separate array to store the resulting array. Instead the elements are added into the original array x. Storing the result in a new array is trivial.
Is there anyway to apply the column-wise calculation as follows?
(each column divided by the last entry of the column)
Eigen::MatrixXd A(3,5), B(3,5);
A << 1, 4, 9, 16, 25,
2, 4, 6, 8, 10,
1, 2, 3, 4, 5;
B = (A.col) / (A.bottomerows<1>).col;
and B would be:
B = 1, 2, 3, 4, 5,
2, 2, 2, 2, 2,
1, 1, 1, 1, 1;
The functions you are looking for are .hnormalized() and .homogeneous(). Both can be applied .colwise() like this:
Eigen::MatrixXd B = A.colwise().hnormalized().colwise().homogeneous();
You can achieve the same with some .replicate() magic like this:
Eigen::MatrixXd B = A.array() / A.row(2).replicate(A.rows(),1).array();
(if A was an ArrayXXd, instead of a MatrixXd, you don't need to write the .array())
I'm trying to find the maximum contiguous subarray with start and end index. The method I've adopted is divide-and-conquer, with O(nlogn) time complexity.
I have tested with several test cases, and the start and end index always work correctly. However, I found that if the array contains an odd-numbered of elements, the maximum sum is sometimes correct, sometimes incorrect(seemingly random). But for even cases, it is always correct. Here is my code:
int maxSubSeq(int A[], int n, int &s, int &e)
{
// s and e stands for start and end index respectively,
// and both are passed by reference
if(n == 1){
return A[0];
}
int sum = 0;
int midIndex = n / 2;
int maxLeftIndex = midIndex - 1;
int maxRightIndex = midIndex;
int leftMaxSubSeq = A[maxLeftIndex];
int rightMaxSubSeq = A[maxRightIndex];
int left = maxSubSeq(A, midIndex, s, e);
int right = maxSubSeq(A + midIndex, n - midIndex, s, e);
for(int i = midIndex - 1; i >= 0; i--){
sum += A[i];
if(sum > leftMaxSubSeq){
leftMaxSubSeq = sum;
s = i;
}
}
sum = 0;
for(int i = midIndex; i < n; i++){
sum += A[i];
if(sum > rightMaxSubSeq){
rightMaxSubSeq = sum;
e = i;
}
}
return max(max(leftMaxSubSeq + rightMaxSubSeq, left),right);
}
Below is two of the test cases I was working with, one has odd-numbered elements, one has even-numbered elements.
Array with 11 elements:
1, 3, -7, 9, 6, 3, -2, 4, -1, -9,
2,
Array with 20 elements:
1, 3, 2, -2, 4, 5, -9, -4, -8, 6,
5, 9, 7, -1, 5, -2, 6, 4, -3, -1,
Edit: The following are the 2 kinds of outputs:
// TEST 1
Test file : T2-Data-1.txt
Array with 11 elements:
1, 3, -7, 9, 6, 3, -2, 4, -1, -9,
2,
maxSubSeq : A[3..7] = 32769 // Index is correct, but sum should be 20
Test file : T2-Data-2.txt
Array with 20 elements:
1, 3, 2, -2, 4, 5, -9, -4, -8, 6,
5, 9, 7, -1, 5, -2, 6, 4, -3, -1,
maxSubSeq : A[9..17] = 39 // correct
// TEST 2
Test file : T2-Data-1.txt
Array with 11 elements:
1, 3, -7, 9, 6, 3, -2, 4, -1, -9,
2,
maxSubSeq : A[3..7] = 20
Test file : T2-Data-2.txt
Array with 20 elements:
1, 3, 2, -2, 4, 5, -9, -4, -8, 6,
5, 9, 7, -1, 5, -2, 6, 4, -3, -1,
maxSubSeq : A[9..17] = 39
Can anyone point out why this is occurring? Thanks in advance!
Assuming that n is the correct size of your array (we see it being passed in as a parameter and later used to initialize midIndexbut we do not see its actual invocation and so must assume you're doing it correctly), the issue lies here:
int midIndex = n / 2;
In the case that your array has an odd number of elements, which we can represented as
n = 2k + 1
we can find that your middle index will always equate to
(2k + 1) / 2 = k + (1/2)
which means that for every integer, k, you'll always have half of an integer number added to k.
C++ doesn't round integers that receive floating-point numbers; it truncates. So while you'd expect k + 0.5 to round to k+1, you actually get k after truncation.
This means that, for example, when your array size is 11, midIndex is defined to be 5. Therefore, you need to adjust your code accordingly.
Suppose I have a matrix and a vector given by. How can I perform a search algorithm like binary search to return the index?
Example:
const int V_SIZE = 10,H_SIZE = 7;
int a1[V_SIZE][H_SIZE] = {
{1,2,0,0,0,0,0},
{1,3,0,0,0,0,0},
{2,2,4,0,0,0,0},
{2,2,6,0,0,0,0},
{3,2,4,7,0,0,0},
{4,1,3,5,9,0,0},
{4,1,4,6,8,0,0},
{4,2,3,4,7,0,0},
{5,2,3,5,7,8,0},
{6,1,3,4,5,7,10}
}; // sorted
int a2 [H_SIZE] = {4,1,3,5,9,0,0};
Perform a search for the vector a2 in the matrix a1 and the return value is 6
Thank a lot
You could use a 2D std::array in combination with std::lower_bound:
const int V_SIZE = 10,H_SIZE = 7;
std::array<std::array<int, H_SIZE>, V_SIZE> a1 {
{{{1,2,0,0,0,0,0}},
{{1,3,0,0,0,0,0}},
{{2,2,4,0,0,0,0}},
{{2,2,6,0,0,0,0}},
{{3,2,4,7,0,0,0}},
{{4,1,3,5,9,0,0}},
{{4,1,4,6,8,0,0}},
{{4,2,3,4,7,0,0}},
{{5,2,3,5,7,8,0}},
{{6,1,3,4,5,7,10}}
}}; // sorted
std::array<int, H_SIZE> a2 {{4,1,3,5,9,0,0}};
int idx = std::lower_bound(std::begin(a1), std::end(a1), a2) - std::begin(a1);
LIVE DEMO
If the matrix is sorted on the first number, you could use binary search to find an approximate index. You then have to go back until you find the first row starting with the same number as in the vector, as well as forward to find the last row starting with the same number. Then you loop over the vector, searching for a match for the second, third, etc. number in the range of rows you have.
What about something like this using std::array?
template <int HSIZE>
bool operator<(const std::array<int, HSIZE> &lhs, const std::array<int, HSIZE> &rhs)
{
for (int i = 0; i < HSIZE; i++)
if (lhs[i] != rhs[i])
return lhs[i] < rhs[i];
return false;
}
std::array<int, 7> a1[] =
{
{ 1, 2, 0, 0, 0, 0, 0 },
{ 1, 3, 0, 0, 0, 0, 0 },
{ 2, 2, 4, 0, 0, 0, 0 },
{ 2, 2, 6, 0, 0, 0, 0 },
{ 3, 2, 4, 7, 0, 0, 0 },
{ 4, 1, 3, 5, 9, 0, 0 },
{ 4, 1, 4, 6, 8, 0, 0 },
{ 4, 2, 3, 4, 7, 0, 0 },
{ 5, 2, 3, 5, 7, 8, 0 },
{ 6, 1, 3, 4, 5, 7, 10 }
};
void search(void)
{
std::array<int, 7> a2 = { 4, 1, 3, 5, 9, 0, 0 };
std::array<int, 7> *a1_end = a1 + sizeof(a1) / sizeof(std::array<int, 7>);
std::array<int, 7> *it = std::lower_bound(a1, a1_end, a2);
}
So I have a pointer to a 2D array like so:
int board[3][5] = { 3, 5, 2, 2, 1, 3, 4, 34, 2, 2, 3, 4, 3, 223, 923 };
int* ptr[sizeof(board[0]) / sizeof(board[0][0])] = board;
I'm trying to follow this example. But for some reason I'm getting the error:
IntelliSense: initialization with '{...}' expected for aggregate
object
Any idea what the problem is?
Assign pointer to the first element of the array like below
int (*ptr)[5] = board;
Note: Column size [5] in the pointer declaration should be equal to the original 2 dimension array column size [5].
Declaring row size [3] is optional.
int main() {
int board[3][5] = { 3, 5, 2, 2, 1, 3, 4, 34, 2, 2, 3, 4, 3, 223, 923 };
/*
// 3 Rows 5 Columns Matrix
int board[3][5] = { {3, 5, 2, 2, 1 },
{3, 4, 34, 2, 2 },
{3, 4, 3, 223, 923}
};
*/
// Assign pointer to the first element of the array
int (*ptr)[5] = board;
for(int i=0; i< (3*5); i++) {
std::cout<<(*ptr)[i]<<std::endl;
}
return 0;
}
A 2D array is not the same as an array of pointers. You cannot directly convert one to the other.
I just needed to put () around the *ptr. I have no idea how this fixes it but now I can do ptr[1][2].