"""
演示
    张量 和 numpy数组 之间的相互转换，以及 只有一个数值的张量 转换为 python数值

涉及到的API:
    张量 转 numpy数组对象：
        张量对象.numpy()      共享内存，浅拷贝，两个变量一起变
        张量对象.numpy().copy() 不共享内存，深拷贝，两个变量不一起变
    numpy数组对象 转 张量：
        torch.from_numpy(numpy数组对象)  共享内存，浅拷贝
        torch.tensor(numpy数组对象)       不共享内存，深拷贝
    一个数值的张量 转 python数值：
        张量对象.item()

需要掌握：
    张量 转 numpy数组对象：
        张量对象.numpy()
    numpy数组对象 转 张量：
        torch.tensor(numpy数组对象)
    一个数值的张量 转 python数值：
        张量对象.item()

"""

# 导包
import torch

# 1.定义函数，演示 张量 和 numpy数组之间 的相互转换
def demo01():
    # 张量 -> numpy数组对象
    # 0.设置随机种子
    torch.manual_seed(5)
    # 1.创建一个随机张量，(3,4)
    t1 = torch.randn(3,4)
    print(f"t1:{t1},ndim: {t1.ndim}, shape: {t1.shape}, type: {type(t1)}, dtype: {t1.dtype}")
    # 2.使用张量对象.numpy(),将张量转为numpy数组
    n1 = t1.numpy()
    print(f"n1:{n1}, shape: {n1.shape},type: {type(n1)}, dtype: {n1.dtype}")
    # 3.演示 共享内存/浅拷贝，两个变量一起变/心灵感灵，改变n1
    n1[0,0] = 100
    print(f"n1:{n1}, shape: {n1.shape}, dtype: {n1.dtype}")
    print(f"t1:{t1}, shape: {t1.shape}, dtype: {t1.dtype}")
    # 4.使用张量对象.numpy().copy(),将张量转为numpy数组
    n2 = t1.numpy().copy()
    print(f"n2:{n2}, shape: {n2.shape}, dtype: {n2.dtype}")
    # # 5.演示 不共享内存/深拷贝，两个变量不一起变，改变n2
    n2[0,0] = 200
    print(f"n2:{n2}, shape: {n2.shape}, dtype: {n2.dtype}")
    print(f"t1:{t1}, shape: {t1.shape}, dtype: {t1.dtype}")

    # numpy数组对象 -> 张量
    # 6.使用torch.from_numpy(numpy数组对象)，将numpy数组转为张量，共享内存，浅拷贝，心灵感应
    t2 = torch.from_numpy(n2)
    print(f"t2:{t2}, shape: {t2.shape}, type: {type(t2)}, dtype: {t2.dtype}")
    t2[0,0] = 10
    print(f"t2:{t2}, shape: {t2.shape}, dtype: {t2.dtype}")
    print(f"n2:{n2}, shape: {n2.shape}, dtype: {n2.dtype}")
    # 7.使用torch.tensor(numpy数组对象)，将numpy数组转为张量,不共享内存/深拷贝
    t3 = torch.tensor(n2)
    print(f"t3:{t3}, shape: {t3.shape}, type:{type(t3)}, dtype: {t3.dtype}")
    t3[0,0] = 20
    print(f"t3:{t3}, shape: {t3.shape}, dtype: {t3.dtype}")
    print(f"n2:{n2}, shape: {n2.shape}, dtype: {n2.dtype}")
    # 8.演示 一个数值的张量 转 python数值，张量对象.item()
    t4 = torch.tensor([[[[10]]]])
    print(f"t4:{t4}, ndim: {t4.ndim}, shape: {t4.shape}, dtype: {t4.dtype}")
    a4 = t4.item()
    print(f"a4:{a4}, type: {type(a4)}")


# 测试
if __name__ == '__main__':
    demo01()