Scilab symbolic matrix multiplication - matrix

I have 3 matrix:
T_01 = ['cosd*t1', '-sind*t1', '0', 'd1*cosd*t1'; 'sind*t1', 'cosd*t1', '0', 'd1*sind*t1'; '0', '1', '1', '0'; '0', '0', '0', '1']
T_12 = ['cosd*t2', '-sind*t2', '0', 'd2*cosd*t2'; 'sind*t2', 'cosd*t2', '0', 'd2*sind*t2'; '0', '1', '1', '0'; '0', '0', '0', '1']
T_23 = ['cosd*t3', '-sind*t3', '0', 'd3*cosd*t3'; 'sind*t3', 'cosd*t3', '0', 'd3*sind*t3'; '0', '1', '1', '0'; '0', '0', '0', '1']
I need to make a symbolic multiplication, so I'm trying:
mulf(T_01,T_12,T_23)
But I get this error:
!--error 39
mulf: Quantidade incorreta de argumentos de entrada: esperava-se 2.
What is happening?
Obs.: Sorry for my english.

If what you want is to get the symbolic multiplication of two matrix, you'll have to implement such function. Here I've implemented three functions that together can perform what you want:
function s = scaProd(a,b)
//escalar product of two vectors
//using recursion
if (a == [] | b == []) then
s = ""
elseif (max(size(a)) ~= max(size(b))) | ...
(min(size(a)) ~= min(size(b))) | ...
(min(size(a)) ~= 1) then
error("vectorMulf: Wrong dimensions")
else
s = addf( mulf(a(1), b(1)) , scaProd(a(2:$), b(2:$)) )
end
endfunction
function s = matrixMulf(a,b)
//matrix multiplication
acols = size(a,'c');
brows = size(b,'r');
if acols ~= brows then
error("matrixMulf: Wrong dimensions")
end
arows = size(a,'r');
bcols = size(b,'c');
s = string(zeros(arows,bcols));
for i = 1 : arows
for j = 1 : bcols
s(i,j) = scaProd(a(i,:),b(:,j)');
end
end
endfunction
function s = addP(a)
//encolses each element of a in a pair of parenthesis
s = string(zeros(a));
for i = 1 : size(a,'r')
for j = 1 : size(a,'c')
s(i,j) = "(" + a(i,j) + ")"
end
end
endfunction
Here is an example of it's output. Test code:
A = [1 2; 3 4];
B = [5 6; 7 8];
C = [9 0; 1 2];
disp(A*B*C)
As = string(A);
Bs = string(B);
Cs = string(C);
disp(matrixMulf(As,addP(matrixMulf(Bs, Cs))))
Console output:
193. 44.
437. 100.
!1*(5*9+6*1)+2*(7*9+8*1) 1*(5*0+6*2)+2*(7*0+8*2) !
! !
!3*(5*9+6*1)+4*(7*9+8*1) 3*(5*0+6*2)+4*(7*0+8*2) !
For the result you want, you should do:
Enclose every term of each of your matrices with parenthesis using addP()
Perform the symbolic multiplication like matrixMulf(t1,addP(matrixMulf(t2,t3))), where t1, t2, t3 are the enclosed versions of your matrices.
And two final notes:
It is important to use addP at each multiplication step to get the correct result. You can check that by removing the ( and ) in the example I gave: the result won't be correct.
The functions mulf and addf are not available on Scilab 6.0.0. So remember you won't be able to use them if you upgrade your Scilab to the current stable version.

Related

PLSQL bitmask values

I am in this situation, I cannot validate the bit for the print permission. Unfortunately I can't have a bitmask with a single bit lit. Can you give me some suggestions?
SELECT
DECODE(BITAND(00000000100000100000000000000001, 1), 1, '1', '0') AS READ,
DECODE(BITAND(00000000100000100000000000000001, 131072), 131072, '1', '0') AS COPY,
DECODE(BITAND(00000000100000100000000000000001, 8388608), 8388608, '1', '0') AS PRINT
FROM
DUAL
The result is the following
R C P
- - -
1 1 0
Can you give me some suggestions?
The BIT_AND function has both arguments as numbers, and there is no bit vector.
For example:
select bin_to_num(0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1) from dual;
OUTPUT>
8519681
with
datum as
(select bin_to_num(0,0,0,0,0,0,0,0,1/*print*/,0,0,0,0,0,1/*copy*/,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1/*read*/) val from dual)
select
decode(bitand(val, 1), 1, '1', '0') as read,
decode(bitand(val, 131072), 131072, '1', '0') as copy,
decode(bitand(val, 8388608), 8388608, '1', '0') as print
from datum

Human matrix convert into zombie [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I face this questing in an interview. Please let me know possible answer for this questing.
We have a matrix like 3 X 3, 5 X 5 or 7 X 7. In mid we do have X(represent zombie) and 0(void or blank) or 1(Human) at all nodes. X created all adjacent human nodes zombie in a minute.
So how much time it will take to create all matrix zombie.
Don't let the terminology fool you: this is a graph problem. I assume that a zombie can also reach the humans that are diagonally adjacent to it.
If you conduct a Breadth first search from the "Zombie point", you will be able to determine that time (if it exists). This is basically how you proceed: (code sample in Python)
matrix = [['1', '0', '0'],['1', 'X', '1'],['0', '0', '0']]
mid = len(matrix)//2
yet_to_explore = [(mid,mid,0)]
explored_set = {} # This is a hashset of explored nodes
while [] != yet_to_explore:
cur_vertex = yet_to_explore.pop(0)
x = cur_vertex[0]
y = cur_vertex[1]
if (x,y) in explored_set:
continue
explored_set[(x,y)] = cur_vertex[2]
matrix[x][y] = 'X'
for i in range(-1,2):
if 0 > x + i or len(matrix) <= x + i:
continue
for j in range(-1,2):
if 0 > y + j or len(matrix) <= y + j:
continue
elif 0 == i and 0 == j:
continue
elif matrix[x+i][y+j]=='1':
yet_to_explore.append((x+i, y+j, cur_vertex[2]+1))
# If your matrix contains a '1' after the BFS this means some human were not reachable (they are isolated) -> the desired time does not exist since not every human can be a zombie
# Else the time you are looking for is the following result:
time = max(list(explored_set.values()))
An example where there is a survivor:
matrix = [['0', '0', '0', '0', '0', '0', '0'],
['1', '1', '1', '1', '0', '0', '0'], # The human on the left will be contamined within 4 min
['0', '0', '0', '1', '0', '0', '0'],
['1', '0', '0', 'X', '0', '0', '0'], # The human on the left will survive
['0', '0', '1', '0', '1', '0', '0'],
['0', '0', '1', '0', '0', '1', '0'],
['0', '1', '0', '0', '0', '0', '1']] # The human on the right will be contamined within 3 min
The search for hypothetical survivors is left as an exercise.

Directly Instansiating a DSP Slice Without IP Core

The Problem
I want:
p <= (d-a) * b
Trying to directly instantiate a DSP block by using a DSP48E1 instead of simply writing p <= (d-a) * b plus it helps me understand how this block works for the future. So far I've had little luck with it though.
Referencing this article:
http://www.xilinx.com/support/documentation/user_guides/ug479_7Series_DSP48E1.pdf
Attempt
These are my current settings:
a <= std_logic_vector(to_unsigned(5, 30));
b <= std_logic_vector(to_unsigned(1, 18));
d <= std_logic_vector(to_unsigned(20, 25));
dsp : DSP48E1
generic map (
USE_DPORT => True,
ALUMODEREG => 0,
CARRYINREG => 0,
CARRYINSELREG => 0,
CREG => 0
)
port map(
clk => clk,
acin => std_logic_vector(to_unsigned(1, 30)), -- cascaded data input
alumode => "0000", -- control bits to select logic unit inputs
bcin => std_logic_vector(to_unsigned(1, 18)), -- cascaded data input
carrycascin => '0', -- cascaded data input
carryin => '0', -- carry input
carryinsel => "000", -- selects carry source
cea1 => '1', -- clock enable if AREG = 2 or INMODE0 = 1
cea2 => '1', -- clock enable if AREG = 1 or 2
cead => '1', -- clock enable for AD pipeline register
cealumode => '0', -- clock enable for ALUMODE --0
ceb1 => '1', -- clock enable if BREG = 1 or INMODE4 = 1
ceb2 => '1', -- clock enable if BREG = 1 or 2
cec => '0', -- clock enable for C
cecarryin => '0', -- clock enable
cectrl => '0', -- clock enable for OPMODE and CARRYINSEL ctrl registers
ced => '1', -- clock enable for D
ceinmode => '0',-- **** clock enable input registers
cem => '0', -- clock enable for the post multiply M register and the internal multiply round CARRYIN register
cep => '1', -- clock enable
inmode => "01101", -- *selects functionality of preadder [3] = sign, [4] = B multiplier sel
multsignin => '0', -- MACC extension sign
opmode => "0000101", -- *** Control input to A, Y and Z multiplexers
pcin => std_logic_vector(to_unsigned(1, 48)), -- cascade input
rsta => rst,
rstallcarryin => '0',
rstalumode => '0',
rstb => rst,
rstc => '0',
rstctrl => rst,
rstd => rst,
rstinmode => rst,
rstm => rst,
rstp => rst,
a => a,--_dsp, -- bits 29:25 used in second stage preadder
b => b,--_dsp,
c => c_dsp,
d => d,--_dsp,
p => p_dsp
);
I always get p = 0 even if I force d = 20, a = 5, b = 1.
I figured I should keep ALUMODE and OPMODE at 0 since I'm skipping the final stage and just want a straight subtraction and multiplication.
Photos
Look at table 2-7 from the DSP48E1 user guide page 34.
Your current configuration performs, at the post-adder, P = Z + X + Y + CIN, with Z = 0, X = 0 and Y = 0. You see the problem here?
The OPMODE signals control the value of the multiplexers. You want OPMODE(6 downto 4) = "000", so that Z keeps its null value. However, you want OPMODE(3 downto 0) = "0101" to set X/Y to the multiplier output M. ALUMODE should keep it's current value, it's fine.

Is there a way to make this code faster and if possible avoid loops?

A1, B1, C1, A2, B2 and C2 are 6 matrix with the same dimensions 4435X2000.
I have to find the values i, j and k for which A1(k,2000) == A2(i,j) and B1(k,2000) == B2(i,j) and C1(k,2000) == C2(i,j) , with the condition X(k)==1 and Y(i,j)==1
The objective is to find: counter, L, T and D
Is there a way to make this code faster? Can I avoid loops?
counter=0;
L(1)=0;
T(1)=0;
D(1)=0;
for k=1:4435
if X(k)==1 % X is a vector (4435x1)
F(k,:) = [A1(k,2000) B1(k,2000) C1(k,2000)]
for i=1:4435
for j=100:1999
if Y(i,j)==1 % Y is a matrix (4435x1999)
if F(k,:) == [A2(i,j) B2(i,j) C2(i,j)]
counter = counter+1;
L(counter)=k;
T(counter)=i;
D(counter)=j;
end
end
end
end
end
end
I want a solution that will save me at least 80% of the computation time!
and not have the error message: Out of memory
See how this works out for you -
%// Store X-Y data by calling X() and Y() functions
X_data = X(1:4435);
Y_data = Y(1:4435,100:1999);
range1 = 100:1999 %// define range for columns
A2 = A2(:,range1); %// Crop out A2, B2, C2 based on column-range
B2 = B2(:,range1);
C2 = C2(:,range1);
Y_data = Y_data(:,range1)==1;
%// Indices for dim-3
idx_X = find(X_data==1)
%// Map X==1 onto A1, B1, C1
A1Lr = A1(X_data==1,end)
B1Lr = B1(X_data==1,end)
C1Lr = C1(X_data==1,end)
%// Setup output array to store L, T, D as single Nx3 output array
out = zeros(sum(Y_data(:))*numel(A1Lr),3);
%// Try out(sum(Y_data(:)==1)*numel(A1Lr),3)=0; instead for speed!
%// Start collecting output indices
count = 1;
for iter1 = 1:numel(A1Lr)
[R,C] = find(Y_data & A2==A1Lr(iter1) & B2==B1Lr(iter1) & C2==C1Lr(iter1));
nR = numel(R);
out(count:count+nR-1,:) = [R C repmat(iter1,nR,1)];
count = count + nR;
end
out(find(out(:,1)==0,1):end,:)=[];
%// Packup the outputs
T = out(:,1)
D = out(:,2) + range1(1)-1
L = idx_X(out(:,3))
It is very difficult to determine what your code is actually supposed to accomplish, without really working to interpret your code. However, I'll give it a crack:
% Determine where X is true.
XTrue = X == 1;
% Extract values from A1,B1,C1 where X is true.
F ( XTrue , 1 : 3 ) = [ A1(XTrue,2000) B1(XTrue,2000) C1(XTrue,2000) ];
% Determine where Y is true.
YTrueIndex = find ( Y == 1 );
% Determine where the extracted values match
counter = [];
L = [];
T = [];
D = [];
for ( ii = 1 : length(YTrueIndex) )
indexCurrent = YTrueIndex(ii)
FRowsThatMatch = F(:,1)==A2(indexCurrent) & F(:,2)==B2(indexCurrent) & F(:,3)==C2(indexCurrent);
matchCount = length ( find ( FRowsThatMatch ) );
if ( matchCount > 0 )
counter = counter + matchCount;
[ i , j ] = ind2sub ( size ( Y ) , indexCurrent );
L = [ L , find ( FRowsThatMatch ) ];
T = [ T , ones(matchCount,1)*i ];
D = [ D , ones(matchCount,2)*j ];
end
end

Cartesian/combination algorithm (while maintaining order)

Since I don't quite know the language of these types of algorithms (i.e. how to google this), I'll just demonstrate what I'm looking for:
I have a three arrays (source arrays are of not equal lengths):
$array1 = array('A', 'B', 'C', 'D');
$array2 = array('x', 'y', 'z');
$array3 = array('1', '2', '3');
I would like all possible combinations of these arrays where:
No more than one element from each source array is taken.
The order of array1, array2, array3 is never broken (ABC always comes before xyz always comes before 123).
So the result would be:
array(
array('A', 'x', '1'),
array('A', 'x', '2'),
array('A', 'x', '3'),
array('A', 'y', '1'),
// etc ...
// But I also need all the partial sets, as long as the rule about
// ordering isn't broken i.e.:
array('B'),
array('B', 'x'),
array('B', 'x', '1'),
array('x'),
array('x', '1'),
array('1'),
);
The order of the results doesn't matter to me.
Working in php, but similar language or pseudo code is fine of course. Or I'd just take a tip on what specific types of permutation/combination algorithms I should be looking at.
I'd say these are Cartesian products. Generating them is quite easy.
for fixed number of arrays (in Perl):
for my $a(#arrayA) {
for my $b(#arrayB) {
push #result, [$a, $b];
}
}
general procedure: Assume #partial is an array for Cartesian product of A1 x A2 x ... x An and we want A1 x ... x An x An+1
for my $a(#partial) {
for my $b(#An_plus_1) {
push #result, [#$a, $b];
}
}
This would obviously need to iterate over all the arrays.
Now, that you want also to omit some of the elements in the sets, you just twist it a little. In the first method, you can just add another element to each of the arrays (undef is obvious choice, but anything will do) and then filter out these elements in the result sets. In the second method, it is even easier: You just add #partial and map { [$_] } #An_plus_1 to the result (or, in English, all the sets resulting from the partial Cartesian product of A1 x ... x An plus the single element sets made form the elements of the new set).
With RBarryYoung's hint, this is the shortest way to produce them, bash (and sed, to remove D, w, and 4):
echo {A..D}{w..z}{1..4} | sed 's/[Dw4]//g'
A1 A2 A3 A Ax1 Ax2 Ax3 Ax Ay1 Ay2 Ay3 Ay Az1 Az2 Az3 Az
B1 B2 B3 B Bx1 Bx2 Bx3 Bx By1 By2 By3 By Bz1 Bz2 Bz3 Bz
C1 C2 C3 C Cx1 Cx2 Cx3 Cx Cy1 Cy2 Cy3 Cy Cz1 Cz2 Cz3 Cz
1 2 3 x1 x2 x3 x y1 y2 y3 y z1 z2 z3 z
Another, easy way, is SQL, which does it by default:
SELECT upper, lower, num
FROM uppers, lowers, numbers
WHERE upper in ('A', 'B', 'C', ' ')
AND lower in (' ', 'x', 'y', 'z')
AND (number in (1, 2, 3) OR number IS NULL);
If your tables only contain 'A,B,C, ,' and 'x,y,z, ,' and '1,2,3, ' it is much shorter:
SELECT upper, lower, num
FROM uppers, lowers, numbers;
Another word, beside cartesian product, for this combinations is cross product.
For an unknown number of unknown size of Lists/Sequences/other collections, I would recommend an Iterator - if PHP has such things. Here is an implementation in Scala:
class CartesianIterator (val ll: Seq[Seq[_]]) extends Iterator [Seq[_]] {
var current = 0
def size = ll.map (_.size).product
lazy val last: Int = len
def get (n: Int, lili: Seq[Seq[_]]): List[_] = lili.length match {
case 0 => List ()
case _ => {
val inner = lili.head
inner (n % inner.size) :: get (n / inner.size, lili.tail)
}
}
override def hasNext () : Boolean = current != last
override def next (): Seq[_] = {
current += 1
get (current - 1, ll)
}
}
val ci = new CartesianIterator (List(List ('A', 'B', 'C', 'D', ' '), List ('x', 'y', 'z', ' '), List (1, 2, 3, 0)))
for (c <- ci) println (c)
List(A, x, 1)
List(B, x, 1)
List(C, x, 1)
List(D, x, 1)
List( , x, 1)
List(A, y, 1)
List(B, y, 1)
...
List( , z, 0)
List(A, , 0)
List(B, , 0)
List(C, , 0)
List(D, , 0)
List( , , 0)
A wrapper could be used to remove the '0' and ' ' from the output.

Resources