【问题标题】:These python functions in c++? [closed]c++中的这些python函数? [关闭]
【发布时间】:2014-02-08 14:44:04
【问题描述】:

我基本上有一些我想理解的 Python 源代码(不是我自己的)。这是一个抗锯齿异或音频振荡器。我根本不知道 python - 但它的可读性很强,除了几件事:

首先 - 完整代码:

f0 = 500.
fs = 44100.
T0 = f0/fs
P0 = fs/f0

t = arange(0,3*fs)
L = len(t)
imax = 2**16


# =============================================================================
# SIGNALS
# =============================================================================

# -----------------------------------------------------------------------------
#
def trivial_xor():
    s = zeros(L)
    sd1 = zeros(L)
    sd2 = zeros(L)
    s = zeros(L)
    w = 0.5
    p = 0
    for n in range(0,L):
        d1 = 2*p - 1
        if p < w:   d2 = 0
        else:           d2 = -0.5
        x1 = int(d1 * imax) & 0xFFFF
        x2 = int(d2 * imax) & 0xFFFF
        y = (x1 ^ x2) / float(imax)
        s[n] = 2*y - 1
        sd1[n] = d1
        sd2[n] = d2
        p += T0
        if p > 1: p -= 1
    return s

# -----------------------------------------------------------------------------
#
def trivial_xor_withSources():
    s = zeros(L)
    sd1 = zeros(L)
    sd2 = zeros(L)
    s = zeros(L)
    w = 0.5
    p = 0
    for n in range(0,L):
        d1 = 2*p - 1
        if p < w:   d2 = 0
        else:           d2 = -0.5
        x1 = int(d1 * imax) & 0xFFFF
        x2 = int(d2 * imax) & 0xFFFF
        y = (x1 ^ x2) / float(imax)
        s[n] = 2*y - 1
        sd1[n] = d1
        sd2[n] = d2
        p += T0
        if p > 1: p -= 1
    return s,sd1,sd2

# -----------------------------------------------------------------------------
#
def PTR1_xor():
    s = trivial_xor() - 2*T0
    #
    T1 = 2*T0
    P1 = 1/T1
    cdc = 1 + T1
    p0 = p1 = 0
    #
    for n in range(0,L):
        if p0 < 0.5:
            h = 0.5
            if p1 < T1:
                s[n] = p1*(2 - 2*h*P1) + 2*h - cdc
        elif p0 < 0.75:
            h = 0.5
            if p1 < T1:
                s[n] = p1*(2 - 2*h*P1) + 2*h - cdc + 1
        else:
            h = 1
            pp = p1 - 0.5
            if pp < T1:
                s[n] = pp*(2 - 2*h*P1) + 2*h - cdc
        #
        p0 += T0
        p1 += T1
        if p0 > 1:  p0 -= 1
        if p1 > 1:  p1 -= 1
    return s

这一切看起来都很简单——除了我认为是缓冲区之外,我只需要知道 c++ 中的这些函数是什么?

////////////////////////////

t = arange(0,3*fs)
L = len(t)
imax = 2**16

////////////////////////////

 def trivial_xor_withSources():
    s = zeros(L)
    sd1 = zeros(L)
    sd2 = zeros(L)
    s = zeros(L)
    w = 0.5
    p = 0
    for n in range(0,L):

我打算实时使用它。其余的看起来就像简单的数学。非常感谢任何帮助!

安德鲁

【问题讨论】:

  • 您甚至没有表明您正在从numpy 导入arange。您反复说明您的代码是多么简单易读,但是您显然缺少行(例如导入),并且只能从函数名称中推断出您要对函数执行的操作。一些解释会很棒。

标签: python c++ file-conversion


【解决方案1】:

如果您尝试将代码转换为 C++,您可以轻松实现(大致)等效的 arange 函数:

#include <vector>

template<typename T>
std::vector<T> arange(T start, T stop, T step = 1) {
    std::vector<T> values;
    for (T value = start; value < stop; value += step)
        values.push_back(value);
    return values;
}

你可以这样使用它:

auto t = arange<double>(0, 3*fs);
auto L = t.length();

** 是取幂。你可以调用pow函数:

#include <cmath>
const double imax = pow(2., 16.);

但由于无论如何您都在处理常量,因此最好:

const double imax = 65536.;

如果您想保留2**16 的表达能力,并且不想招致调用pow 的运行时成本(也许您希望能够更改指数而无需手动重新计算常量),您可以使用constexpr 函数:

constexpr unsigned long power(unsigned long base, unsigned long exponent) {
    return exponent == 0 ? 1 : base * pow(base, exponent - 1);
}

const unsigned long imax = power(2, 16);

【讨论】:

  • 我现在明白了 - 如果实时使用 arange() 可以省略(它与写入文件有关)。您的 c++ arange() 可能会在某个地方派上用场。谢谢!我想我现在什么都明白了!
  • @ichad.c - 虽然从技术上讲,您可以在基于范围的 for 循环(即 for (int i : arange(0, 100))中直接使用 arange,但您会产生创建临时向量的不必要开销。在这种情况下,您最好使用传统的 C(++) for 循环 (for (int i = 0; i &lt; 100; ++i))。
  • 这也是我的结论。我只需要弄清楚 arange() 在做什么。
  • 我在auto t_array = arange&lt;double&gt;(0, 40, dt); 线上收到了error: ‘t_array’ does not name a type——知道我做错了什么吗?据我所知,我已经忠实地修改了您答案中的代码。
  • 我认为template 可能需要与使用arange 的代码位于不同的文件中?我不知道——我是 C++ 新手。
【解决方案2】:

以下是您概述的所有重要行的解释:

  • len(t)表示t的长度”,即数组t的元素个数。

  • 2**16“16 的 2 次方”(C++ 代码中的 1 &lt;&lt; 16)。

  • for n in range(0,L) 等价于for (int n = 0; i &lt; L; ++i)

  • arangezeros 可能是 Numpy 函数。你可以找到他们的参考herehere

关于最后一点,您可能从代码中省略了一些import 语句。

引用自文档:

范围

返回给定间隔内均匀分布的值。

在半开区间 [start, stop) 内生成值(即包含 start 但不包含 stop 的区间)。

默认步长为1,因此t 将是一个包含数字[0, 1, 2, 3, ..., 3 * 44100 - 1] 的数组。

返回给定形状和类型的新数组,用零填充。

zeros 的默认类型是float,因此ssd1sd2 被初始化为由0.0 填充的数组,每个数组都有L 元素。

【讨论】:

  • 是的,我无意中省略了 import def。感谢您的解释!现在一切都有意义了——除了 arange()——但如果我理解正确的话——它与实际处于离线进程/示例中的示例有关,所以希望我可以实时修改它。我以前使用过这种类型的算法,用于简单的 Saw - 但这太疯狂了。
  • 不客气。请考虑accepting the answer
  • 完成了,其实大家每个人的回答都有一点帮助。我不需要 python -> c++ 翻译,我只需要了解 python 语法。谢谢大家!
【解决方案3】:

Python:t = arange(0,3*fs)

C++:double t[] = {0.0,1.0,...,3*fs}; // will not compile of course

Python:L = len(t)

C++:int L = sizeof(t)/sizeof(*t); // where t is an array in the current scope

Python:s = zeros(L)

C++:double s[L] = {0}; // where L is a constant

Python:for n in range(0,L)

C++:for (int i=0; i&lt;L; i++)

【讨论】:

  • 谢谢,帮了大忙!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-15
  • 2022-10-21
相关资源
最近更新 更多