Array Representation of Polynomials - arrays

I was reading about linked list implementation of polynomials. It stated,
Compare this representation with storing the same
polynomial using an array structure.
In the array we have to have keep a slot for each exponent
of x, thus if we have a polynomial of order 50 but containing
just 6 terms, then a large number of entries will be zero in
the array.
I was wondering how do we represent a polynomial in an array? Please guide me.
Thanks

A complete Java implementation of array-based polynomials is here: https://cs.lmu.edu/~ray/classes/dsa/assignment/2/answers/
The basic idea is that if you have a polynomial like
4x^6-2x+5
then your array would look like
0 1 2 3 4 5 6
+----+-----+----+----+----+----+----+
| 5 | -2 | 0 | 0 | 0 | 0 | 4 |
+----+-----+----+----+----+----+----+
That is
the coefficient 5 is in slot 0 of the array (representing 5x^0)
the coefficient -2 is in slot 1 of the array (representing -2x^1)
the coefficient 4 is in slot 6 of the array (representing 4x^6)
You can probably see how this represenation would be wasteful for polynomials like
3x^5000 + 2
In cases like this you want instead to use a sparse array representation. The simplest approach would be to use a map (dictionary) whose keys are the exponoents and whose values are the coefficients.

Suppose your polynomial is
6x^50 + 4x^2 + 2x + 1
The paragraph you have posted is describing storing it in an array like this:
polynomial = new array(50) // I'm assuming all elements initialize to zero
polynomial[50] = 6
polynomial[2] = 4
polynomial[1] = 2
polynomial[0] = 1
Basically its wasting a lot of space this way. Here the array index is the 'power' of x for the polynomial in x.

usually you hold one element for each exponent, so the polynom is actually:
poly[0]*x^0 + poly[1]*x^1 + ... + poly[n-1]*x^(n-1)
for example. if you have p(x) = 3x^5+5x^2+1, your array will be:
poly[0] = 1
poly[1] = 0
poly[2] = 5
poly[3] = 0
poly[4] = 0
poly[5] = 3

If you have a polynomial function like
3x^4 + x^2 + 2x + 1 = 0
You can represent it in array as
[1 2 1 0 3]
So, the element 0 is the coefficient of x^0, element 1 is the coefficient of x^1 and so on...

Related

Minimum sum of absolute difference with th whole array by taking two elements

Hello Everyone,
I am Abhiroop Singh new to the world of competitive programming, recently I came across a question for which i didn't have the faintest idea how to approach it. Being working on the approach for past two days please point me in the righ direction.
So, the questions was,
You are given an array A of N integers. You need to find two integers x and y such that the sum of the absolute difference between each element of the array to one of the two chosen integers is minimal
Task
Determine the minimum value of the expression function if the chosen numbers are x and y
Example
Assumptions
N=4
A = [2,3,6,7]
Approach
•You can choose the two integers, 3 and 7
•The required sum |2-3| + |3-3| + |6-7| + |7-7| = 1 + 0 + 1 + 0 = 2
Constraints
1<= T <= 100
2<= N <=5*10^3
1<= A[i] <=10^6
The sum of N over all test cases does not exceed 5*10^3
Sample input
2
3
1 3 5
4
3 2 5 11
Output
2
3
Explanation
The first line contains the number of test case. T = 2
The first test case
Given
• N = 3
• A = [1,3,5]
Approach
• You can choose the two integers 1 and 4 .
• The required sum = |1-1| + |3-4| + |5-4| = 0 + 1 + 1 = 2.
The second test case
Given
• N = 4
• A = [3, 2, 5, 11]
Approach
• You can choose the two integers, 3 and 11.
• The required sum = |2-3| + |3-3| + |5-3| + |11-11| = 1 + 0 + 2 + 0 = 3.
My approach-:
• First I tried finding median of the array.
• Secondly I tried applying binary search to find the two numbers
Both didn't worked. So, please help me.

MATLAB: Sort a 3d array by another 3d array

I have a 3d array A of random numbers which I'd like to order each k'th dimension individually:
A=rand(3,1,16);
[m, n, k]=size(A);
The array that dictates the order of each matrix in the 3rd dimension is B:
B=randi(3,3,1,16); %this should be without replacement but think it will work anyway
If A(:,1,1)=[0.5, 0.2, 0.6]' and B(:,1,1)=[3,1,2] then the ordered A should be [0.2, 0.6, 0.5]' and so on for each A(:,1,1:k). Please note it's not ordering A numerically.
A(B) is what I might have expected to work and keeps the dimensions but not the right orders.
I've tried to work through this: https://uk.mathworks.com/matlabcentral/answers/307838-sort-3d-matrix-according-to-another-3d-matrix without any success.
Any thoughts would be much appreciated.
To sort A along the k-th dimension based on B: if your data is not complex, a simple way is:
Pack A and B into a complex array where A is the imaginary part and B is the real part;
Sort along the k-th dimension based on the real part;
Keep the imaginary part.
This is done in one line as follows:
result = imag(sort(B+1j*A, k, 'ComparisonMethod', 'real'));
Example:
>> A = rand(2,4,3)
A(:,:,1) =
0.162182308193243 0.311215042044805 0.165648729499781 0.262971284540144
0.794284540683907 0.528533135506213 0.601981941401637 0.654079098476782
A(:,:,2) =
0.689214503140008 0.450541598502498 0.228976968716819 0.152378018969223
0.748151592823709 0.083821377996933 0.913337361501670 0.825816977489547
A(:,:,3) =
0.538342435260057 0.078175528753184 0.106652770180584 0.004634224134067
0.996134716626885 0.442678269775446 0.961898080855054 0.774910464711502
>> B = randi(9, size(A))
B(:,:,1) =
8 1 3 4
8 4 8 9
B(:,:,2) =
2 2 8 5
3 2 6 2
B(:,:,3) =
8 4 4 3
6 5 1 2
>> k = 2;
>> result = imag(sort(B+1j*A, k, 'ComparisonMethod', 'real'))
result(:,:,1) =
0.311215042044805 0.165648729499781 0.262971284540144 0.162182308193243
0.528533135506213 0.601981941401637 0.794284540683907 0.654079098476782
result(:,:,2) =
0.450541598502498 0.689214503140008 0.152378018969223 0.228976968716819
0.083821377996933 0.825816977489547 0.748151592823709 0.913337361501670
result(:,:,3) =
0.004634224134067 0.078175528753184 0.106652770180584 0.538342435260057
0.961898080855054 0.774910464711502 0.442678269775446 0.996134716626885

Rank and unrank fibonacci bitsequence with k ones

For positive integers n and k, let a "k-fibonacci-bitsequence of n" be a bitsequence with k 1 where the 1 on index i describe not Math.pow(2,i) but Fibonacci(i). These positive integers that add up to n, and let the "rank" of a given k- fibonnaci-bitsequence of n be its position in the sorted list of all of these fibonacci-bitsequences in lexicographic order, starting at 0.
For example, for the number 39 we have following valid k-fibonacci-bitsequences, k <=4. The fibonacci numbers behind the fibonacci-bitsequence in this example are following:
34 21 13 8 5 3 2 1
10001000 k = 2 rank = 0
01101000 k = 3 rank = 0
10000110 k = 3 rank = 1
01101100 k = 4 rank = 0
So, I want to be able to do two things:
Given n, k, and a k-fibonacci-bitsequence of n, I want to find the rank of that k-fibonacci-bitsequence of n.
Given n, k, and a rank, I want to find the k-fibonacci-bitsequence of n with that rank.
Can I do this without having to compute all the k-fibonacci-bitsequences of n that come before the one of interest?
Preliminaries
For brevity lets say »k-fbs of n« instead of »k-fibonacci-bitsequences of n«.
Question
Can I do this without having to compute all the k-fbs of n that come before the one of interest?
I'm not sure. So far I still have to compute some of fbs. However, you might have thought we had to start from 00…0 and count up – this is not the case. We can do it the other way around and start from the highest fbs and work our way down very efficiently.
This is not a complete answer. However, there are some observations that could help you:
Zeckendorf
In the following pseudo-code we use the data-type fbs which is basically an array of bools. We can read and write individual bits using mySeq[i] where bit i represents the Fibonacci number fib(i). Just as in your question, the bits myFbs[0] and myFbs[1] do not exist. All bits are initialized to 0 by default. An fbs can be used without [] to read the represented number (n). The helper function #(fbs) returns the number of set bits (k) inside an fbs. Example for n = 7:
fbs meaning representation helper functions
1 0 1 0
| | | `— 0·fib(2) = 0·1 ——— myFbs[2] = 0 #(myFbs) == 2
| | `——— 1·fib(3) = 1·2 ——— myFbs[3] = 1 myFbs == 7
| `————— 0·fib(4) = 0·3 ——— myFbs[4] = 0
`——————— 1·fib(5) = 1·5 ——— myFbs[5] = 1
For any given n we can easily compute the lexicographical maximum (across all k) fbs of n as this fbs happends to be the Zeckendorf representation of n.
function zeckendorf(int n) returns (fbs z):
1 int i := any (ideally the smallest) number such that fib(start) > n
2 while n-z > 0
3 | if fib(i) < n
4 | | z[i] := 1
5 | i := i - 1
zeckendorf(n) is unique and the only fbs of n with k=#(zeckendorf(n)). Therefore zeckendorf(n) has rank=0. Also, there exists no k'-fbs of n with k'<#(zeckendorf(n)).
Transformation
Any k-fbs of n can be transformed into a (k+1)-fbs of n by replacing the bit sequence 100 by 011 anywhere inside the fbs. This works because fib(i)=fib(i-1)+fib(i-2).
If our input k-fbs of n has rank=0 and we replace the right-most 100 then our resulting (k+1)-fbs of n also has rank=0. If we replace the second-right-most 100 our resulting (k+1)-fbs has rank=1 and so on.
You should be able answer both of your questions using repeated transformations starting at zeckendorf(n). For the first question it might even be sufficient to only look at the k-stable transformations 011…100→100…011 and 100…011→011…100 of the given fbs (think about what these transformations do to the rank).

How to find adjacency matrix given a set of links and edges in matlab

I have vector of all edges for example
A = [1;2;3;4];
I also have the matrix of all the links connecting these edges represented by the edge numbers for example
B = [1 3;3 1;1 2;1 2;2 3;4 3];
I would like to construct the adjacency matrix with this data. The matrix should not consider the ordering of the edges in the links For example the second link has edges 1 2 but the matrix should have entries in both 1,2 and 2,1.
So therefore i need an output like this
C = [0 1 1 0;1 0 1 0;1 1 0 1;0 0 1 0];
I cannot think of any other way other than using a for loop for the size of B and then finding the egdes for each link in B and then adding 1's to a pre-initialized 4x4 matrix at i,j where i,j is the link edges.
Is this an efficient way because my real size is many magnitudes greater than 4? Could someone help with a better way to construct the matrix?
You can use sparse to build the matrix, and then optionally convert to full:
result = full(sparse(B(:,1), B(:,2), 1)); % accumulate values
result = result | result.'; % make symmetric with 0/1 values
Equivalently, you can use accumarray:
result = accumarray(B, 1); % accumulate values
result = result | result.'; % make symmetric with 0/1 values
For A = [1;2;3;4]; B = [1 3;3 1;1 2;1 2;2 3;4 3], either of the above gives
result =
4×4 logical array
0 1 1 0
1 0 1 0
1 1 0 1
0 0 1 0

Efficient bit shuffling of vector of binary numbers

I have recorded data containing a vector of bit-sequences, which I would like to re-arrange efficiently. One value in the vector of data could look like this:
bit0, bit1, bit2, ... bit7
I would like to re-arrange this bit-sequence into this order:
bit0, bit7, bit1, bit6, bit2, bit5, bit3, bit4
If I had only one value this would work nicely via:
sum(uint32(bitset(0,1:8,bitget(uint32(X), [1 8 2 7 3 6 4 5]))))
Unfortunately bitset and bitget are not capable of handling vectors of bit-sequences. Since I have a fairly large dataset I am interested in efficient solutions.
Any help would be appreciated, thanks!
dec2bin and bin2dec can process vectors, you can input all numbers at once and permute the matrix:
input=1:23;
pattern = [1 8 2 7 3 6 4 5];
bit=dec2bin(input(:),numel(pattern));
if size(bit,2)>numel(pattern)
warning('input numbers to large for pattern, leading bits will be cut off')
end
output=bin2dec(bit(:,pattern));
if available, I would use de2bi and bi2de instead.
I don't know if I may get the question wrong, but isn't it just solvable by indexing wrapped into cellfun?
%// example data
BIN{1} = dec2bin(84,8)
BIN{2} = dec2bin(42,8)
%// pattern and reordering
pattern = [1 8 2 7 3 6 4 5];
output = cellfun(#(x) x(pattern), BIN, 'uni', 0)
Or what is the format of you input and desired output?
BIN =
'01010100' '00101010'
output =
'00100110' '00011001'
The most efficient way is probably to use bitget and bitset as you did in your question, although you only need an 8-bit integer. Suppose you have a uint8 array X which describes your recorded data (for the example below, X = uint8([169;5]), for no particular reason. We can inspect the bits by creating a useful anonymous function:
>> dispbits = #(W) arrayfun(#(X) disp(bitget(X,1:8)),W)
>> dispbits =
#(W)arrayfun(#(X)disp(bitget(X,1:8)),W)
>> dispbits(X)
1 0 0 1 0 1 0 1
1 0 1 0 0 0 0 0
and suppose you have some pattern pattern according to which you want to reorder the bits stored in this vector of integers:
>> pattern
pattern =
1 8 2 7 3 6 4 5
You can use arrayfun and find to reorder the bits according to pattern:
Y = arrayfun(#(X) uint8(sum(bitset(uint8(0),find(bitget(X,pattern))))), X)
Y =
99
17
We get the desired answer stored efficiently in a vector of 8 bit integers:
>> class(Y)
ans =
uint8
>> dispbits(Y)
1 1 0 0 0 1 1 0
1 0 0 0 1 0 0 0

Resources