C++ 中的 size_t 引发的一个小问题

代码在后面,因为 size_t 是无符号型的,所以在 for 循环中如果疏忽了它的这个符号问题,就会产生比较严重的后果。现在用了一个“临时解决方案”,但是感觉还是不稳妥,暂且记录、稍后再慢慢推敲。

void NetlistManagerClass::CalculateVoltage()
{
	size_t maxRow = this->netlistNodes.size();     //Row 行
	size_t maxColumn = this->netlistNodes.size();  //Column 列

	std::vector<std::vector<double>> A(maxRow, std::vector<double>(maxColumn, 0.0));
	std::vector<double> b(maxRow, 0.0);

	// 遍历网络,完成矩阵和向量的填充
	for(NetlistNodeClass* _netlistNode : this->netlistNodes)
	{
		_netlistNode->fillMatrixAndVector(&A, &b);
	}

	// 完成矩阵和向量的填充之后,开始进行LU求解
	size_t n = this->netlistNodes.size();
	std::vector<double> x = this->solveLinearSystem(A, b, n);

	// 求解得到的就是每一个网络的电压
	std::cout << "Solution: ";
	this->printVector(x, "vector result");
}


// LU分解
void NetlistManagerClass::luDecomposition(const std::vector<std::vector<double>>& A, std::vector<std::vector<double>>& L, std::vector<std::vector<double>>& U, size_t n)
{
	for (size_t i = 0; i < n; i++)
	{
		for (size_t j = i; j < n; j++)
		{
			for (size_t k = 0; k < i; k++)
			{
			}
		}

		for (size_t j = i + 1; j < n; j++)
		{
			for (size_t k = 0; k < i; k++)
			{
			}
		}
	}
}

// 前向替代法
std::vector<double> NetlistManagerClass::forwardSubstitution(const std::vector<std::vector<double>>& L, const std::vector<double>& b, size_t n)
{
	std::vector<double> y(n);
	for (size_t i = 0; i < n; i++)
	{
		y[i] = b[i];
		for (size_t j = 0; j < i; j++)
		{
			y[i] -= L[i][j] * y[j];
		}
	}
	return y;
}

// 后向替代法
std::vector<double> NetlistManagerClass::backwardSubstitution(const std::vector<std::vector<double>>& U, const std::vector<double>& y, size_t n)
{
	//for(size_t i = n-1; i>=0; i--) // 存在bug
	//for (int i = n - 1; i >= 0; i--) // 可以解决问题,但是变量类型不一致
	for (size_t i = n - 1; i != size_t(-1); i--)
	{
		for (size_t j = i + 1; j < n; j++)
		{
		}
	}
	return x;
}

// 求解线性方程组
std::vector<double> NetlistManagerClass::solveLinearSystem(std::vector<std::vector<double>>& A, std::vector<double>& b, size_t n)
{
    std::vector<std::vector<double>> L(n, std::vector<double>(n, 0));
    std::vector<std::vector<double>> U(n, std::vector<double>(n, 0));
    luDecomposition(A, L, U, n);
    std::vector<double> y = forwardSubstitution(L, b, n);
    return backwardSubstitution(U, y, n);
}

以前上学的时候觉得所有的知识都挺容易理解的,现在也许是年龄大了,即便是对已经已经熟练掌握了的知识,再看的时候,都会感觉是“一头雾水”,唯有继续艰难的、一点点的重新理解,才能让自己感觉有所收获。

Related Posts

找到个对OPC学习有益的开源项目

没有经历过任何OPC相关的工作,连这方面的设备都没有上手摸到过,所以也就对OPC的概念和技术完全没有任何的感性认知了。 现在完全凭空的感觉是,OPC是一种“通信框架”,虽然它的名字是Ole Process Control,但是这其中的Process Control只是说他能达到的目的,而不是它的实现。它能够通过信号传递以达到过程控制的目的,其本质还是要先完成信号的传递、也就是数据的传输与交换。 在Server端和Client端进行的数据传输,并不是简单的“字符串”,而是一个Ole封装对象。这有点儿像今天比较流行的json对象,不过与json对象不同,ole对象是微软提出并不断发展起来的。 无论是Server端、还是Client端,都将自己要发出的数据先封装成ole对象,然后再通过彼此事先完成的公共约定、也就是OPC数据传输机制,将这个ole对象发送或接收。接收到ole对象之后再解析出其中需要的具体内容(有可能是数据、信号量、字符串、甚至是图形、声音、或设备专有的某些高级数据封装形式)。 上面就是我此刻对OPC的初步理解和认知。 找到了一个GitHub上面的小项目,实现的非常简单,但正是如此简单的项目才更有助于理解这个对我而言的“新鲜事物”。项目地址是:https://github.com/feremabraz/OPCUA-Client-Server 使用C#编写,并且有服务端、客户端的基础实现。令人满意的,它还特意实现了一个图形化的客户端,以便能够方便的看出Server端上所有可用的信号Key值。 因为这个项目实现的非常简单,几乎没有任何依赖、也没有多少语句,所以编译十分迅速。这对于初学者十分友好,即便稍后想读一读它的代码,相信也能够十分轻松的完成阅读和理解。 启动服务端时遇到了一点小障碍:无论怎么运行Server端都是直接结束掉,我一度以为是缺少管理员权限。后来发现是不应在控制台中直接运行,而是要在VS环境下启动,至于其中具体的原因还没有推敲。总之先能够把大面跑起来再说。 启动Server端之后,运行Client端,就能够连上Server,并且拉取Server上的全部信息。也可以手动指定其中某一条信息(某一个信号)将其结果拉取回来。使用控制台Client时不清楚所有信号的key信息是什么,可以通过Client-GUI方便的观察到,这样对比着验证key是哪些、应该拉取回来的value是多少,就方便多了。 整体而言,这个项目:能够正常启动OPC Server,通过Client能够正常连接、并拉取会数据,意味着他们之间的通信是建立了的。基于此,就可以进一步了解、学习OPC相关的知识了。