<% unless type_name == 'robject' %> void <%="cumo_#{c_iter}_stride_kernel_launch"%>(char *ptr, ssize_t s0, ssize_t s1, ssize_t kofs, dtype data, uint64_t n0, uint64_t n1); <% end %> #include static void <%=c_iter%>(cumo_na_loop_t *const lp) { size_t n0, n1; ssize_t s0, s1; char *p0; char *g; ssize_t kofs; dtype data; g = (char*)(lp->opt_ptr); kofs = *(ssize_t*)g; data = *(dtype*)(g+sizeof(ssize_t)); n0 = lp->args[0].shape[0]; n1 = lp->args[0].shape[1]; s0 = lp->args[0].iter[0].step; s1 = lp->args[0].iter[1].step; p0 = CUMO_NDL_PTR(lp,0); <% if type_name == 'robject' %> { size_t i0, i1; char *p1; CUMO_SHOW_SYNCHRONIZE_FIXME_WARNING_ONCE("<%=name%>", "<%=type_name%>"); for (i0=0; i0 < n0; i0++) { p1 = p0; for (i1=0; i1 < n1; i1++) { *(dtype*)p1 = (i0+kofs==i1) ? data : m_zero; p1 += s1; } p0 += s0; } } <% else %> <%="cumo_#{c_iter}_stride_kernel_launch"%>(p0,s0,s1,kofs,data,n0,n1); <% end %> } /* Eye: Set a value to diagonal components, set 0 to non-diagonal components. @overload <%=name%>([element,offset]) @param [Numeric] element Diagonal element to be stored. Default is 1. @param [Integer] offset Diagonal offset from the main diagonal. The default is 0. k>0 for diagonals above the main diagonal, and k<0 for diagonals below the main diagonal. @return [Cumo::<%=class_name%>] <%=name%> of self. */ static VALUE <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self) { cumo_ndfunc_arg_in_t ain[1] = {{CUMO_OVERWRITE,2}}; cumo_ndfunc_t ndf = {<%=c_iter%>, CUMO_NO_LOOP, 1,0, ain,0}; ssize_t kofs; dtype data; char *g; int nd; cumo_narray_t *na; // check arguments if (argc > 2) { rb_raise(rb_eArgError,"too many arguments (%d for 0..2)",argc); } else if (argc == 2) { data = m_num_to_data(argv[0]); kofs = NUM2SSIZET(argv[1]); } else if (argc == 1) { data = m_num_to_data(argv[0]); kofs = 0; } else { data = m_one; kofs = 0; } CumoGetNArray(self,na); nd = na->ndim; if (nd < 2) { rb_raise(cumo_na_eDimensionError,"less than 2-d array"); } // Diagonal offset from the main diagonal. if (kofs >= 0) { if ((size_t)(kofs) >= na->shape[nd-1]) { rb_raise(rb_eArgError,"invalid diagonal offset(%"SZF"d) for " "last dimension size(%"SZF"d)",kofs,na->shape[nd-1]); } } else { if ((size_t)(-kofs) >= na->shape[nd-2]) { rb_raise(rb_eArgError,"invalid diagonal offset(%"SZF"d) for " "last-1 dimension size(%"SZF"d)",kofs,na->shape[nd-2]); } } g = ALLOCA_N(char,sizeof(ssize_t)+sizeof(dtype)); *(ssize_t*)g = kofs; *(dtype*)(g+sizeof(ssize_t)) = data; cumo_na_ndloop3(&ndf, g, 1, self); return self; }