Matlab числовой тип / эквивалент переинтерпретации в python? - PullRequest
8 голосов
/ 07 августа 2020

В Matlab есть команда для определения нового типа numeri c, например:

numerictype(0,16,8) 

см. Документацию: https://www.mathworks.com/help/fixedpoint/ref/embedded.numerictype.html

Есть ли эквивалент в numpy или другой библиотеке? Могу ли я создать свой собственный dtype с помощью аналогичной команды?

РЕДАКТИРОВАТЬ:

Поскольку меня попросили предоставить дополнительную информацию, вот ссылка на то, как типы чисел с фиксированной точкой c работают в Matlab: https://www.mathworks.com/help/dsp/ug/concepts-and-terminology.html в основном вы устанавливаете подписанный / беззнаковый характер, а затем, как долго должно быть слово вместе с дробной длиной. Так, например, в приведенном мною примере у вас будет число со знаком с длиной слова 16 и дробной длиной 10.

Из того, что я читал о структурированных массивах, похоже, что подобное представление может быть чем-то вроде строки:

dtype=[('signed', np.bool_), ('word', np.int16), ('frac', np.int16)]) 

Моя конечная цель состоит в том, чтобы достичь трех отдельных операторов повторного преобразования, а именно:

reinterpretcast(EVMacq,numerictype(0,16,8))
reinterpretcast(Payload16c,numerictype(1,16,16))
reinterpretcast(Payload32,numerictype(1,32,32))

Если есть способ сделать это проще, я более чем счастлив сделайте это по-другому.

Вот расшифровка информации, которую я добавил в комментариях:

mathworks.com / help / fixedpoint / ref / reinterpretcast. html вот документация реинтерпретации из матлаб. По сути, вы передаете целое число или число с фиксированной точкой, а функция как бы перемещает десятичную точку. Это делает это так, даже если двоичные данные не изменились, числовое значение переменной c другое.

Иногда вы можете добиться аналогичного эффекта для определенных диапазонов чисел путем нормального деления, но это не надежное и нежелательное решение.

Я мог бы сам написать что-нибудь, что бы это сделал, но я бы предпочел, если бы это уже сделал кто-то более умный, чем я. Учитывая, что большая часть функций Matlab включена в numpy, я подумал, что это тоже будет. Структурированные массивы могут быть хорошим выбором, но я не уверен, как именно работает приведение к ним.

РЕДАКТИРОВАТЬ:

Теперь я понимаю, что на самом деле просто хочу отточить одну-единственную команду, если кто-то может сказать мне, как сделать что-то в точности эквивалентное этому приведению, я буду очень рад, поскольку я все еще не могу понять это из. Скорость - не проблема, ее просто нужно запустить.

Вот команда:

reinterpretcast(Payload16c,numerictype(1,16,16)) где Payload16 c - это массив комплексных чисел, определяемый как np.complex(real,imag). Заранее спасибо.

Я пробовал что-то подобное, и это не сработало, но, возможно, на правильном пути. Мне кажется, что какой-то коэффициент масштабирования отличается от того, что произошло бы в MatLab, но каждый раз не тот же коэффициент масштабирования:

    i = 0
    result = []

    #first generate a binary number that is a one in the highest spot and zero elsewhere
    comp = 2**wordlength
    #next iterate through entire array
    while i < array.size:

        #check to see if the value of the item is near the largest value it can be
        #if so its likely that it is just negative and thats why that bit is high
        if(array[i:i+1] < ((2**fracbits)-1000)):
            #if it is not near the largest number simply convert divide to move decimal place
            real = array[i:i+1] * (2**-fracbits) 
        else:
            #else we subtract comp so that we get the negative number this binary string was supposed to represent.
            # print(np.binary_repr(np.uint16(array[i:i+1])))
            real = double(array[i:i+1]) - comp 

            #then we divide it to move the decimal point properly
            real = real * (2**-fracbits)

        #same for the next number in the array which is the imaginary component
        if(array[i+1:i+2] < ((2**fracbits)-2000)):
            imag = array[i+1:i+2] * (2**-fracbits)
        else:
            imag = double(array[i+1:i+2]) - comp
            imag = imag * (2**-fracbits)

        result.append(np.complex(real,imag))
        i+=2
    return result

Ответы [ 2 ]

2 голосов
/ 26 августа 2020

С точки зрения Python программистов, попадание в чушь с типами данных противоречит природе самого python. python динамически типизирован , что подразумевает неэффективность, но простоту программирования. Чтобы обойти это, многие популярные библиотеки написаны на c, поэтому вы можете посмотреть библиотеки, такие как numpy, чтобы получить исправление ввода. Вот пример установки типов данных в numpy. Но, насколько мне известно, они работают только с предварительно определенными c типами

, теоретически вы можете определить специальный класс для хранения ваших данных, реализующий __add__, __subtract__ и любые другие ключевые функции необходимы. Однако, поскольку python динамически типизирован, это может иметь практически ограниченный возврат.

Еще одним вариантом может быть Cython , который позволяет вам определять типы C в python, но если вам просто нужна быстрая функция для определения типа, основная природа Python борется против вас.

0 голосов
/ 27 августа 2020

Вы можете использовать np.dtype. Я использовал ваше представление dtype в следующем фрагменте:

import numpy as np
dtype=[('signed', np.bool_), ('word', np.int16), ('frac', np.int16)] 
mytype = np.dtype(dtype)

, и вы можете использовать его в таком массиве:

np.array([True,1,1],dtype=mytype)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...