return type based on content of an array
Hi, I'm going circles... ;) I read a string that contains an array of unknown dimension like: a = [1,2,3,4] or a = [[1,2],[3,4]] or a = [[[1,2],[3,4]],[[5,6],[7,8]]] With that I want to perform specified operations e.g. also provided on command line. Because at compile time the dimension of the array is unkown I did not find any possibility to do something like: auto arr = func(a); where 'auto func(string str)' should return either a 1D, 2D, 3D array and arr is not locked in an if(){} scope. Is there any way and What should I'm looking for? Thanks, thorstein
Re: confused with data types
Thanks for all the insights :)
Re: confused with data types
On Sunday, 18 February 2018 at 12:51:04 UTC, thorstein wrote: Thank you for the very informative answers showing different gears in D! However, there are still some details I'm struggling with: Assume some calculations on a very big numeric array 'double[][][] arr'. Now we could choose 1 out of 3 different implementations: // Solution 1 foreach(row; arr) { foreach(col; row) { col[] *= skalar; } } return arr; // Solution 2 import std.array; return array(arr.map!(b => array(b[].map!(c => array(c[].map!(d => d * skalar)); // Solution 3 import std.algorithm; arr.each!(a => a[].each!(b => b[] *= skalar)); return arr; Q#1: Does the compiler optimizes all solutions equally strong or does it prefer implementations like solution 1? Q#2: Solution 2 is a 1-liner but a bit harder to read. Why reducing solution 3 to: return arr.each!(a => a[].each!(b => b[] *= skalar)); gives a compile error? I do writeln() the function result. Q#3: If I can: static import std.array; return std.array.array(arr.map!(b => std.array.array(b[].map!(c =>... How would I apply a similar version with 'static import std.algorithm' to solution 3? static import std.algorithm; std.algorithm.arr.each!(a => a[]... //does obviously not work Thanks, thorstein Sorry, Solution 2 should be: import std.array; return array(arr.map!(b => array(b[].map!(c => c[] *= skalar; and is as readable as Solution 3. However, Q#2 still remains.
Re: confused with data types
Thank you for the very informative answers showing different gears in D! However, there are still some details I'm struggling with: Assume some calculations on a very big numeric array 'double[][][] arr'. Now we could choose 1 out of 3 different implementations: // Solution 1 foreach(row; arr) { foreach(col; row) { col[] *= skalar; } } return arr; // Solution 2 import std.array; return array(arr.map!(b => array(b[].map!(c => array(c[].map!(d => d * skalar)); // Solution 3 import std.algorithm; arr.each!(a => a[].each!(b => b[] *= skalar)); return arr; Q#1: Does the compiler optimizes all solutions equally strong or does it prefer implementations like solution 1? Q#2: Solution 2 is a 1-liner but a bit harder to read. Why reducing solution 3 to: return arr.each!(a => a[].each!(b => b[] *= skalar)); gives a compile error? I do writeln() the function result. Q#3: If I can: static import std.array; return std.array.array(arr.map!(b => std.array.array(b[].map!(c =>... How would I apply a similar version with 'static import std.algorithm' to solution 3? static import std.algorithm; std.algorithm.arr.each!(a => a[]... //does obviously not work Thanks, thorstein
confused with data types
Hello, This was my goal: - public double[][] skalar_m_2d(double[][] array, double skalar) { return array.map!(b => b[].map!(c => c * skalar)); } !!! But: return value is not double! Type check for return value: a = array.map!(b => b[].map!(c => c * skalar)) writeln(typeof(a).stringof); //-> MapResult!("__lambda4, double[][]) a = array.map!(b => b[].map!(c => c * skalar))[1]; writeln(typeof(a).stringof); //-> MapResult!("__lambda2, double[]) How can I get the result as double[][] ??? Thanks, thorstein
conversion error related to array index
Hi, I get the following compile error with this function below: source\mod_data\matrices.d(66,12): Error: cannot implicitly convert expression (j) of type ulong to uint (66,12) is [j] in row[j] Using uint as type for rows, cols (i.e. the indices) works. Is ulong not allowed for array indices? I could not find the respective information. Thanks! 49 private double[][] matrix_uniform(ulong rows, ulong cols, double lbound, double ubound, ulong precision) 50 { 51double[][] array; 52double[] rowT; 53auto gen = Random(unpredictableSeed); 54auto rndUniform = uniform(lbound, ubound, gen); 55 56foreach(ulong i; 0..cols) 57{ 58 rowT ~= 0; 59} 60 61foreach(ulong i; 0..rows) 62{ 63 foreach(ulong j; 0..cols) 64 { 65rndUniform = uniform(lbound, ubound, gen); 66rowT[j] = to!double(rndUniform) / 10^^precision; 67 } 68 array ~= rowT.dup; 69} 70 return array; 71 }
Re: how to use unknown size of array at compile time for further processing
Replace arrayT ~= rowT; with arrayT ~= rowT.dup; Also, you may want to look into ndslice package [1]. [1] https://github.com/libmir/mir-algorithm Best regards, Ilya Yaroshenko Works! Thanks Ilya. I'll take a look on the difference. Also soon will get bit familiar with the mir-algorithm... Best, Torsten
Re: how to use unknown size of array at compile time for further processing
Guyes, I obviously made a mistake. Forget my post! Sorry, I'm still really confused with the results from my function: double[][] transp(double[][] array) { double[][] arrayT; double[] rowT; // initialize rowT foreach(i; 0..array.length) { rowT ~= 0; } foreach(col; 0..array[0].length-3) { foreach(row; 0..array.length) { rowT[row] = array[row][col]; } writeln("rowT 1: ",rowT); writeln("arrayT 1: ", arrayT); arrayT ~= rowT; writeln("rowT 2: ",rowT); writeln("arrayT 2: ", arrayT,"\n"); } return arrayT; } Again, assuming my original array to be: array = [ [ 4, 3, 1, 5, 2], [19, 34, 23, 100, 59], [62, 1, 4, 0, 76], [23, 6, 989, 98, 1], [ 5, 87, 45, 62, 9], [ 5, 87, 45, 62, 9] ]; ... the results are strange. Before the appending (arrayT ~= rowT;) happens for the second column of array arrayT was miraculous modified: rowT 1: [4, 19, 62, 23, 5, 5] arrayT 1: [] rowT 2: [4, 19, 62, 23, 5, 5] arrayT 2: [[4, 19, 62, 23, 5, 5]] rowT 1: [3, 34, 1, 6, 87, 87] arrayT 1: [[3, 34, 1, 6, 87, 87]] rowT 2: [3, 34, 1, 6, 87, 87] arrayT 2: [[3, 34, 1, 6, 87, 87], [3, 34, 1, 6, 87, 87]] etc... Is there any linkage between rowT and arrayT Thanks again!
Re: how to use unknown size of array at compile time for further processing
On Sunday, 1 October 2017 at 13:53:57 UTC, thorstein wrote: Why is that Thanks! Guyes, I obviously made a mistake. Forget my post!
Re: how to use unknown size of array at compile time for further processing
They are not alternatives. They are the only way of doing things. Yes, sounds logic - static arrays require a size before compilation. However, I tried another variation with a totally unexpected result: double[][] transp3(double[][] array) { double[][] arrayT; double[] rowT; // initialize rowT foreach(i; 0..array.length) { rowT ~= 0; } foreach(col; 0..array[0].length) { foreach(row; 0..array.length) { rowT[row] = array[row][col]; } arrayT ~= rowT; writeln("rowT: ",rowT); writeln("arrayT: ", arrayT); } return arrayT; } Assuming my original array to be: array = [ [ 4, 3, 1, 5, 2], [19, 34, 23, 100, 59], [62, 1, 4, 0, 76], [23, 6, 989, 98, 1], [ 5, 87, 45, 62, 9], [ 5, 87, 45, 62, 9] ]; ...then the printed result is unexpectedly wrong. The transposed columns (rowT) are correct, but arrayT ~= rowT doesn't only append rowT to arrayT. It overrides also the previous rows with the new transposed column: rowT: [4, 19, 62, 23, 5, 5] arrayT: [[4, 19, 62, 23, 5, 5]] rowT: [3, 34, 1, 6, 87, 87] arrayT: [[3, 34, 1, 6, 87, 87], [3, 34, 1, 6, 87, 87]] etc... Why is that Thanks!
how to use unknown size of array at compile time for further processing
Hi, assumed, I need the size of a dynamic array for further processing, which is unknown at compile time. Below are my example, which doesn't work and two alternatives. Alternative1: may create large rowT-arrays depending on original array size. Alternative2: overrides rowT after exiting the inner loop (which may be costly?) How could I implement something like the first approach? Thanks! // Not working example of transposing a matrix double[][] transp(double[][] array) { double[][] arrayT; double[array[0].length] rowT; foreach(col; 0..array[0].length) { foreach(row; array) { rowT[col]= row[col]; } arrayT ~= rowT; } return arrayT; } // Alternative1 double[][] arrayT; double[] rowT; foreach(col; 0..array[0].length) { foreach(row; array) { rowT ~= row[col]; } arrayT ~= rowT[$-6..$]; } // Alternative2 double[][] arrayT; foreach(col; 0..array[0].length) { double[] rowT; foreach(row; array) { rowT ~= row[col]; } arrayT ~= rowT; }
Re: questions about dub
Ups, somehow overread the last sentence of tourge :) Thanks for the detailed insights!
Re: questions about dub
Thanks to all, I got it! I created a new dub package and copied my code there. Compiles. So I guess I get the rest working as well. Still will have to figure out later the procedure to do the same for a VisualD project, if it is possible. Thorstein
questions about dub
Hi, I have questions regarding the usage of 'dub'. I'm learning D under Win7. I have installed VisualD for the community edition of Visual Studio and got some file i/o working. Next I would like to continue with the mir-tools for matrix manipulation. I understood that I have to build them first using dub. But I didn't succeed: C:\..\AppData\Roaming\dub>dub fetch mir-algorithm Fetching mir-algorithm 0.1.1... Please note that you need to use `dub run ` or add it to dependencies of your package to actually use/run it. dub does not do actual installation of packages outside of its own ecosystem. C:\..\AppData\Roaming\dub>dub run mir-algorithm Building package mir-algorithm in C:\..\AppData\Roaming\dub\packages\mir-algorithm-0.1.1\mir-algorithm\ Fetching mir-internal 0.0.5 (getting selected version)... Main package must have a binary target type, not sourceLibrary. Cannot build. Thats where I stuck. Beside my specific problem of how to start with the mir-tools I wonder how and for what purpose 'dub' is applied when building projects in connection with Visual Studio? Or is it just a more light-weight command line build tool? Thanks for shedding some light! Thorstein
Re: code D'ish enough? - ignore previous post with same subject
On Sunday, 26 February 2017 at 21:50:38 UTC, Jordan Wilson wrote: auto readNumMatCsv2 (string filePath, string ndv, string new_ndv){ double[][] p_numArray; try { auto lines = File(filePath,"r").byLine; lines.popFront; // get read of header p_numArray = lines.map!(a => a.replace (ndv,new_ndv) .splitter (",") .map!(a => a.to!double) .array) .array; } catch (Exception e){ e.msg.writeln; // this replaces "Could not read file. Quit here." } return p_numArray; } It took me quite a while to get the whole usage of range stuff like "map" and "filter" etc., but I think it's worth the effort. This looks like more friendly readable compact code, where should be the goal. Thanks for your insights!
Re: code D'ish enough? - ignore previous post with same subject
I really appriciate your comments and thoughts! On Sunday, 26 February 2017 at 21:02:52 UTC, ag0aep6g wrote: On Sunday, 26 February 2017 at 19:34:33 UTC, thorstein wrote: * "no-data-value"? No-data-values in data sets are common at least in geosciences: raster images, spatial simulation outputs etc. Not all cells have evaluable information and need to be filtered by a specific very high or very low numeric value. And different software may require different no-data-values. * It's not obvious to me what "Mat" means in "readNumMatCsv". means 'read numeric matrix from csv-like files'
code D'ish enough? - ignore previous post with same subject
Hi, sorry for posting again, but I used a keyboard combination that accidently send my post before it was done. Coming more or less from Python I just started with D. Not a real programmer, just automating things and looking for a neat compiled language. Just to learn, I wrote a function to read CSV-like files (I know D has its own routine). Since I'm still a bit overwhelmed by the many complex language features, I'm curious what could I change to make my code as D'ish as possible? Thank you for any suggestion, Thorstein // Reads CSV-like files with only numeric values in each column // new_ndv replaces ndv, which is the original no-data-value double[][]* readNumMatCsv(char[] filePath, int numHeaderLines, char[] ndv, char[] new_ndv) { double[][]* p_numArray; double[][] numArray; char[] line; string noCont = "File content not usable. Quit here."; string noFile = "Could not read file. Quit here."; string nonNum = "Found a non-numeric value in data matrix. Quit here."; Regex!char re = regex(r"(\n$)"); if(exists(filePath)) { File f = File(filePath, "r"); if((line = f.readln().dup).length > 0) { while (!f.eof()) // 1st replace ndv with new_ndv, 2nd remove all \n, 3rd check id size of read line >0 { if((line = replaceAll(f.readln().dup.replace(ndv, new_ndv), re, "")).length > 0) // check if all elements of splitted line are numeric { foreach(i;split(line,",")) { if(isNumeric(i) == false) // otherwise return pointer to empty array { writeln(nonNum); return p_numArray; } } // convert characters to double if(split(line,",").length > 0) { numArray ~= to!(double[])(split(line,",")); } } } // pass reference to pointer p_numArray = // first line empty -> return pointer to empty array } else { writeln(noCont); } // file could not be find } else { writeln(noFile); } return p_numArray; }
code D'ish enough?
Hi, coming more or less from Python I just started with D. Not a real programmer, just automating things and looking for a neat compiled language. Just to learn, I wrote a function to read CSV-like files (I know D has its own routine). Since I'm still a bit overwhelmed by the many complex language features, I'm curious what could I change to make my code as D'ish as possible? Thank you for any suggestion, Thorstein // Reads CSV-like files with only numeric values in each column // new_ndv replaces ndv, which is the original no-data-value double[][]* readNumMatCsv(char[] filePath, char[] ndv, char[] new_ndv) { double[][]* p_numArray; double[][] numArray; char[] line; string noCont = "File content not usable. Quit here."; string noFile = "Could not read file. Quit here."; string nonNum = "Found a non-numeric value in data matrix. Quit here."; Regex!char re = regex(r"(\n$)"); if(exists(filePath)) { File f = File(filePath, "r"); if((line = f.readln().dup).length > 0) { while (!f.eof()) { if((line = replaceAll(f.readln().dup.replace(ndv, new_ndv), re, "")).length > 0) { foreach(i;split(line,",")) { if(isNumeric(i) == false) { writeln(nonNum); return p_numArray; } } if(split(line,",").length > 0) { numArray ~= to!(double[])(split(line,",")); } } } p_numArray = } else { writeln(noCont); } } else { writeln(noFile); } return p_numArray; }