Esempio n. 1
0
double DistanceTwoVertices(double* vertices, unsigned numVertices, vtkIdType* edgeEnds)
{
    double x_diff = acces_2d(vertices, edgeEnds[0], 0, numVertices) - acces_2d(vertices, edgeEnds[1], 0, numVertices);
    double y_diff = acces_2d(vertices, edgeEnds[0], 1, numVertices) - acces_2d(vertices, edgeEnds[1], 1, numVertices);
    
    double dist = sqrt(x_diff*x_diff + y_diff*y_diff);
    return dist;
}
void mexFunction( int nlhs, mxArray *plhs[], 
		  int nrhs, const mxArray*prhs[] )
     
{
    double cellSurfaceAreaToVolumeRatio = mxGetScalar( mxGetField(prhs[0], 0, "cellSurfaceAreaToVolumeRatio") );
    double cellMembraneCapacitance = mxGetScalar( mxGetField(prhs[0], 0, "cellMembraneCapacitance") );
    double leftConductivity = mxGetScalar( mxGetField(prhs[0], 0, "leftConductivity") );
    double pdeTimeStep = mxGetScalar( mxGetField(prhs[0], 0, "pdeTimeStep") );
    double spaceStep = mxGetScalar( mxGetField(prhs[0], 0, "spaceStep") );
    double rightConductivity = mxGetScalar( mxGetField(prhs[0], 0, "rightConductivity") );
    unsigned numberCells = mxGetScalar( mxGetField(prhs[0], 0, "numberCells") );
        
    double surfaceRatioTimesCapacitance = cellSurfaceAreaToVolumeRatio * cellMembraneCapacitance;
    double leftCondutivityTimesTimeStepOverSpaceStepSquared = leftConductivity * pdeTimeStep / (spaceStep*spaceStep);
    double rightCondutivityTimesTimeStepOverSpaceStepSquared = rightConductivity * pdeTimeStep / (spaceStep*spaceStep);        
    
    // Create a dense matrix
    mxArray* denseMatrix = mxCreateDoubleMatrix(numberCells, numberCells, mxREAL);
    
    // Get a C pointer to the dense matrix 
    double *systemMatrix = mxGetPr(denseMatrix);

    unsigned rowIndex;
    double condutivityTimesTimeStepOverSpaceStepSquared;
    
    // Fill in matrix row 0
    acces_2d(systemMatrix,0,0,numberCells) = surfaceRatioTimesCapacitance + 2*leftCondutivityTimesTimeStepOverSpaceStepSquared;
    acces_2d(systemMatrix,0,1,numberCells) = -2*leftCondutivityTimesTimeStepOverSpaceStepSquared;

    // Fill in rows 1 to numberCells-2
    for (rowIndex=1;rowIndex<numberCells-1;rowIndex++)
    {
        // Determine which conductivity to use (left half or right half)
        if (rowIndex < (numberCells)/2)
        {
            condutivityTimesTimeStepOverSpaceStepSquared = leftCondutivityTimesTimeStepOverSpaceStepSquared;
        }
        else
        {
            condutivityTimesTimeStepOverSpaceStepSquared = rightCondutivityTimesTimeStepOverSpaceStepSquared;
        }
    
        acces_2d(systemMatrix,rowIndex,rowIndex-1,numberCells) = -condutivityTimesTimeStepOverSpaceStepSquared;
        acces_2d(systemMatrix,rowIndex,rowIndex,numberCells) = surfaceRatioTimesCapacitance + 2*condutivityTimesTimeStepOverSpaceStepSquared;
        acces_2d(systemMatrix,rowIndex,rowIndex+1,numberCells) = -condutivityTimesTimeStepOverSpaceStepSquared;
    }

    // Fill in row numberCells-1
    acces_2d(systemMatrix,numberCells-1,numberCells-2,numberCells) = -2*rightCondutivityTimesTimeStepOverSpaceStepSquared;
    acces_2d(systemMatrix,numberCells-1,numberCells-1,numberCells) = surfaceRatioTimesCapacitance + 2*rightCondutivityTimesTimeStepOverSpaceStepSquared;    
    
    // Do the conversion from dense to sparse (the output goes into plhs, ready to be returned by the MEX function)
    mexCallMATLAB(1,&plhs[0],1,&denseMatrix,"sparse");
    
    // We don't need the dense matrix anymore
    mxDestroyArray(denseMatrix);
    
    return;
}
Esempio n. 3
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
{
    // Check for proper number of arguments
    if (nrhs!=6) 
    { 
	    mexErrMsgTxt("Six input argument required."); 
    } 
    else if (nlhs>1) 
    {
	    mexErrMsgTxt("Too many output arguments provided."); 
    } 

    // Get access to MATLAB data through C data types
    double *vertices = mxGetPr(prhs[0]);
    unsigned num_vertices = mxGetM(prhs[0]);
    
    double *edges = mxGetPr(prhs[1]);
    unsigned num_edges = mxGetM(prhs[1]);

    double *radii = mxGetPr(prhs[2]);
    unsigned num_radii_values = mxGetM(prhs[2]);
    
    std::string dataset_name(mxArrayToString(prhs[3]));
    
    double pixel_to_um = mxGetScalar(prhs[4]);
    
    double radii_fudge_factor = mxGetScalar(prhs[5]);
    
    if (num_vertices != num_radii_values)
    {
        mexErrMsgTxt("Number of radii values provided differs from the number of vertices specified.");
    }
    
    // Create the output variable that will store the edge lengths and radii required for one of the histograms
    plhs[0] = mxCreateDoubleMatrix(num_edges, 2, mxREAL);
    double *edge_length_radii = mxGetPr(plhs[0]);
    
    // Create and fill a point container
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    for (unsigned vertex=0; vertex<num_vertices; vertex++)
    {
        points->InsertNextPoint(acces_2d(vertices, vertex, 0, num_vertices) * pixel_to_um, 
                                acces_2d(vertices, vertex, 1, num_vertices) * pixel_to_um, 
                                0);
    }
 
    // Create a polydata object and add the points to it.
    vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
    polydata->SetPoints(points);

    // Create the array containing edge lengths 
    vtkSmartPointer<vtkDoubleArray> lengths_array = vtkSmartPointer<vtkDoubleArray>::New();
    lengths_array->SetNumberOfComponents(1);
    lengths_array->SetName("EdgeLengths");
    
    // Allocate memory and add the definition of edges to the polydata object
    polydata->Allocate();
    vtkIdType edge_ends[2];    
    for (unsigned edge_id=0; edge_id<num_edges; edge_id++)
    {
        // The definition of edges comes from MATLAB and and the vertices are one-based indexed. Offset them.
        edge_ends[0] = acces_2d(edges, edge_id, 0, num_edges) - 1; 
        edge_ends[1] = acces_2d(edges, edge_id, 1, num_edges) - 1;
        
        polydata->InsertNextCell(VTK_LINE, 2, edge_ends);
        double edge_length = DistanceTwoVertices(vertices, num_vertices, edge_ends) * pixel_to_um;
        lengths_array->InsertNextValue(edge_length);
        
        acces_2d(edge_length_radii, edge_id, 0, num_edges) = edge_length;
        acces_2d(edge_length_radii, edge_id, 1, num_edges) = radii_fudge_factor * pixel_to_um * (radii[edge_ends[0]] + radii[edge_ends[1]])/2;
    }
    //polydata->GetCellData()->AddArray(lengths_array);
    
    // Create and fill the array containing the plexus radii at each vertex.
    vtkSmartPointer<vtkDoubleArray> radii_array = vtkSmartPointer<vtkDoubleArray>::New();
    radii_array->SetNumberOfComponents(1);
    radii_array->SetName("Radius");    
    for (unsigned vertex_id=0; vertex_id<num_vertices; vertex_id++)
    {
        radii_array->InsertNextValue(radii_fudge_factor * radii[vertex_id] * pixel_to_um);
    }
    polydata->GetPointData()->AddArray(radii_array);
    polydata->GetPointData()->SetActiveScalars("Radius");
     
    WritePolyDataToDisk(polydata, dataset_name + ".vtp");
}