2

I am learning Numpy as a substitute to Matlab. I am having problem mapping Matlab function to Numpy. Program is to add two signals using Matlab

Matlab version :

function [y.d = sigadd(xl,nl,x2,n2)
% implements y(n) = xi(n)+x2(n)
% [y,nl - sigadd(xi,nl,x2,n2)
X
% xi = first sequence over nl
% x2 - second sequence over n2 (n2 can be different from nl)
%
n = min(min(n1) ,min(n2)) :max(max(nl) ,max(n2)) ; X duration of y(n)
yl - zeros(l,length(n)); y2 = yl;
yl(find((n>=min(nl))&(n<cmar(nl))-l))lxl;
y2(find((n>=min(n2))&(n<=max(n2))==1))=x2;
y = yl+y2;

I have tried the following in Python :

def SigAdd(x1,n1,x2,n2):
    n_l =  min(min(n1),min(n2))
    n_h=  max(max(n1),max(n2))
    n = arange(n_l,n_h+1)
    y1 = zeros([1,len(n)],int)
    y2 = y1
    y1 = (argwhere((n>=min(n1))&(n<=max(n1)))==1)
    y1 = x1
    y2 = (argwhere((n>=min(n2))&(n<=max(n2)))==1)
    y2 = x2
    y = y1 + y2
    return y,n

Expected Results:

Example1: Arrays of unequal length

x1 = array([1,1,1,1,1])
x2 = array([1,1,1,1])
n1 = array([1,2,3,4,5])
n2 = array([1,2,3,4])
y,n = SigAdd(x1,n1,x2,n2)
>> y 
array[2,2,2,2,1]
>>n
array[1,2,3,4,5]

Example2:Arrays of equal length

x1 = array([1,1,1])
x2 = array([1,1,1])
n1 = array([1,2,3])
n2 = array([3,4,5])
y,n = SigAdd(x1,n1,x2,n2)
>> y 
array[1,1,2,1,1]
>>n
array[1,2,3,4,5]

It works fine if both the arrays are of equal length, but won't work for unequal arrays. I know the problem is i am overriding the y1 (which i initially created with zeros) with value of x1 causing problem. I have used argwhere command in Numpy which is equivalent to Find command of Matlab, but if I use it like Matlab program shown above, it shows error that value can't be assigned to callable function.

Basically in Matlab program, unequal arrays are filled with zero's. Matlab version handles condition even if two signals are of equal length but are at different positions. I want to use Python instead of Matlab but these conversion problems are causing pain.

Some Modifications : (But is not working, Indexing Error : Out of bound coming)

def SigAdd(x1,n1,x2,n2):
    n_l =  min(min(n1),min(n2))
    n_h=  max(max(n1),max(n2))
    n = arange(n_l,n_h+1)
    y1 = zeros([1,len(n)],int)
    y2 = y1
    y11 = argwhere((n>=min(n1))&(n<=max(n1)))
    q = 0
    for w in y11:
        y1[w]= x1[q]
        q = q + 1
    y22 = argwhere((n>=min(n2))&(n<=max(n2)))
    q = 0
    for w in y22:
        y2[w]= x2[q]
        q = q + 1
    y = y1 + y2
    return y
2
  • I would write a little function that pads an array with zeros to the size you want, so that you can always pass arrays of equal length to SigAdd(). Commented Sep 26, 2012 at 6:21
  • Padding may not work for example2, i have modified code to address this problem, but i am just stuck with assignment. Commented Sep 26, 2012 at 6:24

3 Answers 3

4

You can assign to a slice:

def SigAdd(x1,n1,x2,n2):
    n_l = min(n1[0], n2[0])
    n_h = max(n1[-1], n2[-1])
    n = arange(n_l, n_h+1)
    y = zeros(len(n), int)
    i = n1[0] - n[0]
    y[i:i+len(x1)] = x1
    i = n2[0] - n[0]
    y[i:i+len(x2)] += x2
    return y
Sign up to request clarification or add additional context in comments.

3 Comments

Thx, It is working, but can you please check why my modified code is showing "Out of bound index error".
@sarbjit I think the problem is that this is a 2-dimensional array: y1 = zeros([1,len(n)],int)
You are right, it was a 2-D array and i was using just a single index to refer it, fixed it. Thanks a lot.
2

Using fancy indexing:

import numpy as np
high = max(n2[-1], n1[-1])
low = min(n2[0], n1[0])
n1_ = n1 - low  # use 0-based indexing
n2_ = n2 - low
y = np.zeros(high - low + 1, dtype=x1.dtype)
y[n1_] += x1
y[n2_] += x2

Comments

0

This helped me for a similar problem. The idea is to first make the vectors equal length (with 0 padding the shorter at the end). Disadvantages are the conversion to lists and the memory overhead with those lists. However for quick and dirty tasks it has served well.

def MakeVectorsSameSize(v1,v2):
  """given two vectors zero pad smaller to match length of bigger"""
  #make the vectors length of longest 0 pad
  l1 = len(v1)
  l2 = len(v2)
  if l1 < l2:
    #put l2-l1 elements into v1
    z1 = numpy.ones(l2-l1)*0
    v1 = list(v1)
    v1.extend(z1)
    v1 = numpy.array(v1)
  elif l1 > l2:
    #put l1-l2 elements into v2
    z2 = numpy.ones(l1-l2)*0
    v2 = list(v2)
    v2.extend(z2)
    v2 = numpy.array(vTemp)

  return v1,v2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.