1// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab 2// Copyright (C) INRIA 3// 4// Copyright (C) 2012 - 2016 - Scilab Enterprises 5// 6// This file is hereby licensed under the terms of the GNU GPL v2.0, 7// pursuant to article 5.3.4 of the CeCILL v.2.1. 8// This file was originally licensed under the terms of the CeCILL v2.1, 9// and continues to be available under such terms. 10// For more information, see the COPYING file which you should have received 11// along with this program. 12 13function M = generic_i_hm(default_value,varargin) 14 15 16 //insertion of a matrix in an hypermatrix 17 [lhs,rhs]=argn(0) 18 rhs=rhs-1 19 M=varargin(rhs); 20 N=varargin(rhs-1);//inserted matrix 21 22 dims=matrix(size(M),-1,1); 23 v=matrix(M,-1,1); 24 25 nd=size(dims,"*") 26 olddims=dims 27 28 // adjust dimension of matrix M to number of indices 29 reduced_index=%f 30 if rhs-2>nd then 31 dims(nd+1:rhs-2)=0; 32 elseif rhs-2<nd then //less indices than M number of dims 33 dims=[dims(1:rhs-3);prod(dims(rhs-2:$))] 34 if size(find(dims>1),"*")>1 then reduced_index=%t,end 35 end 36 37 //handling special case M(....)=[] 38 if N==[] then 39 // at most only one index should not match the full 40 // corresponding dimension 41 // if yes insertion is the extraction of the complement. 42 ok=[]; 43 for k=1:rhs-2 44 dk=varargin(k) 45 if or(type(dk)==[2 129]) then 46 dk=horner(dk,dims(k)), 47 elseif type(dk)==4 then 48 dk=find(dk) 49 end 50 if or(size(dk)<>-1) then 51 dk=gsort(dk); 52 if or(dk<>(dims(k):-1:1)) then 53 if dk(1)<1|dk($)>dims(k) then 54 error(msprintf(_("%s: Invalid index.\n"), "generic_i_hm")) 55 end 56 if ok<>[] then 57 msg = _("%s: A null assignment can have only one non-colon index.\n") 58 error(msprintf(msg, "generic_i_hm")); 59 end 60 ok=k 61 I1=1:dims(k);I1(dk)=[] 62 varargin(k)=I1 63 end 64 end 65 66 end 67 68 if size(ok,"*")==0 then 69 M=[] 70 else //use extraction 71 [Ndims,I]=convertindex(dims,varargin(1:$-2)); 72 dims(ok)=size(I1,"*") 73 while dims($)==1&size(dims,"*")>2, dims($)=[],end 74 M=M(I); 75 M=matrix(M, dims) 76 end 77 78 return 79 end 80 81 //convert N-dimensional indexes to 1-D and extend dims if necessary 82 [Ndims,I]=convertindex(list(dims,size(N)),varargin(1:$-2)); 83 Ndims=matrix(Ndims,-1,1) 84 85 //if reduced_index & or(Ndims<>dims), error(msprintf(_("%s: Invalid index.\n"), "generic_i_hm")), end 86 if or(Ndims>dims) then 87 //extend the destination matrix 88 I1=0 89 for k=size(Ndims,"*"):-1:1 90 ik1=(1:dims(k))'; 91 if ik1<>[] then 92 if Ndims(k)>1 then 93 if size(I1,"*")>1 then 94 I1=(Ndims(k)*I1).*.ones(ik1)+ones(I1).*.(ik1-1); 95 else 96 I1=Ndims(k)*I1+ik1-1; 97 end 98 else 99 I1=Ndims(k)*I1+ik1-1; 100 end 101 end 102 end 103 // create the resulting matrix 104 v2=[];v2(1:prod(Ndims),1)=default_value; 105 // populate it with M entries 106 if v<>[] then v2(I1+1)=v;end 107 else 108 v2=v 109 end 110 //insert N entries into result 111 v2(I)=N(:) 112 113 //remove trailing unitary dimensions 114 if reduced_index then 115 Ndims=olddims 116 else 117 while Ndims($)==1 then Ndims($)=[],end 118 select size(Ndims,"*") 119 case 0 then 120 Ndims=[1,1] 121 case 1 then 122 k=find(olddims<>1&olddims<>0) 123 if k==[]|Ndims>prod(olddims) then //shape changed 124 if oldEmptyBehaviour("query")=="off" then 125 Ndims=[1,Ndims] 126 else 127 Ndims=[Ndims,1] 128 end 129 else 130 Ndims=olddims; 131 end 132 else 133 if N==[] 134 Ndims=matrix(Ndims,1,-1) 135 end 136 end 137 end 138 M=matrix(v2,Ndims) 139endfunction 140