How to solve the following errors in this code in visual studio 2022 version: expected an identifier on line 33
identifier "otherUser" is undefined on line 33 expected a']' on line 33 identifier "ratings" is undefined on line 38 language feature 'structured bindings' requires compiler flag 'std:c++17' on line 33
#include <iostream>
#include <map>
#include <vector>
#include <cmath>
#include <xlnt/xlnt.hpp>
// Define a type alias for a map that maps a user ID to a vector of ratings
using UserRatings = std::map<int, std::vector<double>>;
// Define a function to calculate the cosine similarity between two users
double cosineSimilarity(const std::vector<double>& user1, const std::vector<double>& user2) {
// Initialize variables to store the dot product and the magnitudes of the vectors
double dotProduct = 0.0;
double magnitude1 = 0.0;
double magnitude2 = 0.0;
// Calculate the dot product and magnitudes of the vectors
for (size_t i = 0; i < user1.size(); i++) {
dotProduct += user1[i] * user2[i];
magnitude1 += user1[i] * user1[i];
magnitude2 += user2[i] * user2[i];
}
// Calculate and return the cosine similarity
return dotProduct / (sqrt(magnitude1) * sqrt(magnitude2));
}
// Define a function to predict the rating of a movie for a given user
double predictRating(const UserRatings& userRatings, int user, int movie) {
// Initialize variables to store the predicted rating and the sum of the similarities
double prediction = 0.0;
double sumSimilarities = 0.0;
// Iterate over all users in the userRatings map
for (const auto& [otherUser, ratings] : userRatings) {
// Skip the current user
if (otherUser == user) continue;
// Calculate the similarity between the current user and the other user
double similarity = cosineSimilarity(userRatings.at(user), ratings);
// If the similarity is positive, add it to the sum of similarities and
// add the other user's rating for the movie to the prediction
if (similarity > 0) {
sumSimilarities += similarity;
prediction += similarity * ratings[movie];
}
}
// Return the predicted rating for the movie
return prediction / sumSimilarities;
}
int main() {
// Load the data from an Excel file
xlnt::workbook workbook;
workbook.load("ratings.xlsx");
xlnt::worksheet sheet = workbook.active_sheet();
// Create a map of user ratings
UserRatings userRatings;
for (auto row : sheet.rows()) {
int user = row[0].value<int>();
std::vector<double> ratings;
for (auto cell : row) {
if (cell.column() == 1) continue;
ratings.push_back(cell.value<double>());
}
userRatings[user] = ratings;
}
// Predict the rating of movie 3 for user 1
double prediction = predictRating(userRatings, 1, 3);
std::cout << "Predicted rating for movie 3 by user 1: " << prediction << std::endl;
return 0;
}
I want to implement dataset from an excel file
In your code we could see that the code lacks the definition of the following variables, you need to define them according to your requirements.
feature 'structured bindings' requires compiler flag 'std:c++17' on
line 33
For this error, you need to right click on the project and select project properties, then set C++ Language Standard to c++17.
Related
I wanna get backPropagation proccess into a file in the most detail possible.
I've tried adding ofstream File as Attribute for Matrix class to write methods results via ofstream append to file but then most Matrices in SimpleNeuralNetwork class were marked with error (for example _weightMatrices).
class SimpleNeuralNetwork
{
public:
std::vector<uint32_t> _topology;
std::vector<Matrix2D<float>> _weightMatrices;
std::vector<Matrix2D<float>> _valueMatrices;
std::vector<Matrix2D<float>> _biasMatrices;
float _learningRate;
public:
// topology defines the no.of neurons for each layer
// learning rate defines how much modification should be done in each backwords propagation i.e. training
SimpleNeuralNetwork(std::vector<uint32_t> topology,float learningRate = 0.1f)
:_topology(topology),
_weightMatrices({}),
_valueMatrices({}),
_biasMatrices({}),
_learningRate(learningRate)
{
bool backPropagate(std::vector<float> targetOutput)
{
if(targetOutput.size() != _topology.back())
return false;
// determine the simple error
// error = target - output
Matrix2D<float> errors(targetOutput.size(), 1);
errors._vals = targetOutput;
errors = errors.add(_valueMatrices.back().negetive());
// back propagating the error from output layer to input layer
// and adjusting weights of weight matrices and bias matrics
for(int32_t i = _weightMatrices.size() - 1; i >= 0; i--)
{
//calculating errrors for previous layer
Matrix2D<float> prevErrors = errors.multiply(_weightMatrices[i].transpose());
//calculating gradient i.e. delta weight (dw)
//dw = lr * error * d/dx(activated value)
Matrix2D<float> dOutputs = _valueMatrices[i + 1].applyFunction(DSigmoid);
Matrix2D<float> gradients = errors.multiplyElements(dOutputs);
gradients = gradients.multiplyScaler(_learningRate);
Matrix2D<float> weightGradients = _valueMatrices[i].transpose().multiply(gradients);
//adjusting bias and weight
_biasMatrices[i] = _biasMatrices[i].add(gradients);
_weightMatrices[i] = _weightMatrices[i].add(weightGradients);
errors = prevErrors;
}
}
I wanted to calculate p-values of a t-statistic for a two tailed test with 5% level of significance. And I wanted to do this with the standard library. I was wondering if this was possible using the student_t_distribution from the < random > module.
My code currently is as following
#include <iostream>
int main(){
double t_stat = 0.0267; // t-statistic
double alpha_los = 0.05; // level of significance
double dof = 30; // degrees of freedom
// calculate P > |t| and compare with alpha_los
return 0;
}
Thank you
The <random> header just provides you with the ability to get random numbers from different distributions.
If you are able to use boost you can do the following:
#include <boost/math/distributions/students_t.hpp>
int main() {
double t_stat = 0.0267; // t-statistic
double alpha_los = 0.05; // level of significance
double dof = 30; // degrees of freedom
boost::math::students_t dist(dof);
double P_x_greater_t = 1.0 - boost::math::cdf(dist, t_stat);
double P_x_smaller_negative_t = boost::math::cdf(dist, -t_stat);
if(P_x_greater_t + P_x_smaller_negative_t < alpha_los) {
} else {
}
}
Part of a program that I'm working on implements a function that takes in the package weight as an argument and calculates the shipping cost based on that weight. The criteria for the cost/lb is as follows:
Package Weight Cost
-------------- ----
25 lbs & under $5.00 (flat rate)
26 - 50 lbs above rate + 0.10/lb over 25
50 + lbs above rate + 0.07/lb over 50
I used an if-if else-if to make the calculations, but feel like its a bit repetitive:
const int TIER_2_WEIGHT = 25;
const int TIER_3_WEIGHT = 50;
const float TIER_1_RATE = 5.00;
const float TIER_2_RATE = 0.10;
const float TIER_3_RATE = 0.07;
float shipPriceF;
if(shipWeightF <= TIER_2_WEIGHT)
{
shipPriceF = TIER_1_RATE;
}
else if(shipWeightF <= TIER_3_WEIGHT)
{
shipPriceF = ((shipWeightF - TIER_2_WEIGHT) * TIER_2_RATE) +
TIER_1_RATE;
}
else
{
shipPriceF = ((shipWeightF - TIER_3_WEIGHT) * TIER_3_RATE) +
((TIER_3_WEIGHT - TIER_2_WEIGHT) * TIER_2_RATE) +
TIER_1_RATE;
}
return shipPriceF;
So, the question is... is this the best way to accomplish this task, or should I be looking for a different solution?
First at all, you code looks clear and ok as it is.
Of course, you could deduplicate the redundant parts of the formulas by using a cumulative approach:
float shipPriceF = TIER_1_RATE; // to be paid anyway
if (shipWeightF > TIER_2_WEIGHT) // add the tier 2 if necessary
{
shipPriceF += (min(shipWeightF, TIER_3_WEIGHT) - TIER_2_WEIGHT) * TIER_2_RATE;
}
if(shipWeightF > TIER_3_WEIGHT) // add the tier 3 if really necessary
{
shipPriceF += (shipWeightF - TIER_3_WEIGHT) * TIER_3_RATE);
}
Well, this could even be simplified further:
float shipPriceF = TIER_1_RATE
+ max(min(shipWeightF,TIER_3_WEIGHT)-TIER_2_WEIGHT,0) * TIER_2_RATE
+ max(shipWeightF-TIER_3_WEIGHT,0) * TIER_3_RATE;
For 3 scales, it's probably ok with this synthetic formula. If you want more flexibility however, you could think of iterating throug a vector of rates instead of using constants. This would allow for a variable number of scales. If you're sure that the formula is always progressive (eg. "above + new unit price for what's exceding") use then the cumulative approach.
I think there are a lot of nearly identical lines in the code but not real duplicates. If you add more rates you can easily copy the wrong macro definitions or mix the values from the wrong rate.
My code itself removes the if/else replications and avoid the need of using the correct global definition. If you add a new rate to my code you simply add a raw to the table.
Only to give an idea what else can be done:
#include <iostream>
#include <functional>
#include <limits>
// first we define a entry of a table. This table contains the limit to which the ratio is valid and
// a function which calculates the price for that part of the weight.
struct RateTableEntry
{
double max;
std::function<double(double, double)> func;
};
// only to shrink the table width :-)
constexpr double MAX = std::numeric_limits<double>::max();
// and we define a table with the limits and the functions which calculates the price
RateTableEntry table[]=
{
// first is flate rate up to 25
{ 25, [](double , double )->double{ double ret= 5.00; return ret; }},
// next we have up to 50 the rate of 0.10 ( use min to get only the weight up to next limit
{ 50, [](double max, double weight)->double{ double ret= std::min(weight,max)*0.10; return ret; }},
// the same for next ratio. std::min not used, bedause it is the last entry
{ MAX, [](double , double weight)->double{ double ret= weight *0.07; return ret; }}
};
double CalcRate(double weight)
{
std::cout << "Price for " << weight;
double price = 0;
double offset = 0;
for ( auto& step: table )
{
// call each step, until there is no weight which must be calculated
price+=step.func(step.max- offset, weight);
// reduce the weight for that amount which allready is charged for
weight-=step.max-offset;
// make the table more readable, if not used this way, we have no max values but amount per step value
offset+=step.max;
if ( weight <= 0 ) break; // stop if all the weight was paid for
}
std::cout << " is " << price << std::endl;
return price;
}
int main()
{
CalcRate( 10 );
CalcRate( 26 );
CalcRate( 50 );
CalcRate( 51 );
CalcRate( 52 );
CalcRate( 53 );
}
If C++11 is not available, you also can use normal functions and function pointers instead of lambdas and std::function.
I am reading in a temperature value every 1 second/minute (this rate is not crucial). I want to measure this temperature so that if it begins to rise rapidly above a certain threshold I perform an action.
If the temperature rises above 30 degrees ( at any rate ) I increase the fan speed.
I think I must do something like set old temperature to new temp and then each time it loops set old temp to the current temp of the engine. But I am not sure if I need to use arrays for the engine temp or not.
Of course you can store just one old sample, then check difference like in:
bool isHot(int sample) {
static int oldSample = sample;
return ((sample > 30) || (sample - oldSample > threshold));
}
It's OK from C point of view, but very bad from metrology point of view. You should consider some conditioning of your signal (in this case temperature) to smothen out any spikes.
Of course you can add signal conditioning letter on. For (easy) example look at Simple Moving Avarage: https://en.wikipedia.org/wiki/Moving_average
If you want control the fan speed "right way" you should consider learning a bit about PID controller: https://en.wikipedia.org/wiki/PID_controller
Simple discrete PID:
PidController.h:
class PidController
{
public:
PidController();
double sim(double y);
void UpdateParams(double kp, double ki, double kd);
void setSP(double setPoint) { m_setPoint = setPoint; } //set current value of r(t)
private:
double m_setPoint; //current value of r(t)
double m_kp;
double m_ki;
double m_kd;
double m_outPrev;
double m_errPrev[2];
};
PidController.cpp
#include "PidController.h"
PidController::PidController():ControllerObject()
{
m_errPrev[0] = 0;
m_errPrev[1] = 0;
m_outPrev = 0;
}
void PidController::UpdateParams(double kp, double ki, double kd)
{
m_kp = kp;
m_ki = ki;
m_kd = kd;
}
//calculates PID output
//y - sample of y(t)
//returns sample of u(t)
double PidController::sim(double y)
{
double out; //u(t) sample
double e = m_setPoint - y; //error
out = m_outPrev + m_kp * (e - m_errPrev[0] + m_kd * (e - 2 * m_errPrev[0] + m_errPrev[1]) + m_ki * e);
m_outPrev = out; //store previous output
//store previous errors
m_errPrev[1] = m_errPrev[0];
m_errPrev[0] = e;
return out;
}
I am trying to do a simple matrix inversion operation using boost. But I
am getting an error.
Basically what I am trying to find is inversted_matrix =
inverse(trans(matrix) * matrix)
But I am getting an error
Check failed in file boost_1_53_0/boost/numeric/ublas/lu.hpp at line 299:
detail::expression_type_check (prod (triangular_adaptor<const_matrix_type,
upper> (m), e), cm2)
terminate called after throwing an instance of
'boost::numeric::ublas::internal_logic'
what(): internal logic
Aborted (core dumped)
My attempt:
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/lu.hpp>
namespace ublas = boost::numeric::ublas;
template<class T>
bool InvertMatrix (const ublas::matrix<T>& input, ublas::matrix<T>& inverse) {
using namespace boost::numeric::ublas;
typedef permutation_matrix<std::size_t> pmatrix;
// create a working copy of the input
matrix<T> A(input);
// create a permutation matrix for the LU-factorization
pmatrix pm(A.size1());
// perform LU-factorization
int res = lu_factorize(A,pm);
if( res != 0 )
return false;
// create identity matrix of "inverse"
inverse.assign(ublas::identity_matrix<T>(A.size1()));
// backsubstitute to get the inverse
lu_substitute(A, pm, inverse);
return true;
}
int main(){
using namespace boost::numeric::ublas;
matrix<double> m(4,5);
vector<double> v(4);
vector<double> thetas;
m(0,0) = 1; m(0,1) = 2104; m(0,2) = 5; m(0,3) = 1;m(0,4) = 45;
m(1,0) = 1; m(1,1) = 1416; m(1,2) = 3; m(1,3) = 2;m(1,4) = 40;
m(2,0) = 1; m(2,1) = 1534; m(2,2) = 3; m(2,3) = 2;m(2,4) = 30;
m(3,0) = 1; m(3,1) = 852; m(3,2) = 2; m(3,3) = 1;m(3,4) = 36;
std::cout<<m<<std::endl;
matrix<double> product = prod(trans(m), m);
std::cout<<product<<std::endl;
matrix<double> inversion(5,5);
bool inverted;
inverted = InvertMatrix(product, inversion);
std::cout << inversion << std::endl;
}
Boost Ublas has runtime checks to ensure among other thing numerical stability.
If you look at source of the error, you can see that it tries to make sure that
U*X = B, X = U^-1*B, U*X = B (or smth like that) are coorect to within some epsilon. If you have too much deviation numerically this will likely not hold.
You can disable checks via -DBOOST_UBLAS_NDEBUG or twiddle with BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN.
As m has only 4 rows, prod(trans(m), m) cannot have a rank higher than 4, and as the product is a 5x5 matrix, it must be singular (i.e. it has determinant 0) and calculating the inverse of a singular matrix is like division by 0. Add independent rows to m to solve this singularity problem.
I think your matrix dimension, 4 by 5, caused the error. Like what Maarten Hilferink mentioned, you may try with a square matrix like 5 by 5. Here are requirement to have an inverse:
The matrix must be square (same number of rows and columns).
The determinant of the matrix must not be zero (determinants are covered in section 6.4). This is instead of the real number not being zero to have an inverse, the determinant must not be zero to have an inverse.